1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

workaround for browser connection limits

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
Jari Kolehmainen 2021-02-08 22:46:31 +02:00
parent 73195c2f14
commit c134d322a9
5 changed files with 29 additions and 16 deletions

View File

@ -194,7 +194,8 @@ export class LensProxy {
if (proxyTarget) {
// allow to fetch apis in "clusterId.localhost:port" from "localhost:port"
res.setHeader("Access-Control-Allow-Origin", this.origin);
// this should be safe because we have already validated cluster uuid
res.setHeader("Access-Control-Allow-Origin", "*");
return proxy.web(req, res, proxyTarget);
}

View File

@ -55,17 +55,28 @@ export class JsonApi<D = JsonApiData, P extends JsonApiParams = JsonApiParams> {
return this.request<T>(path, params, { ...reqInit, method: "get" });
}
getReadableStream(path: string, params?: P, init: RequestInit = {}): Promise<Response> {
let reqUrl = this.config.apiBase + path;
getResponse(reqUrl: string, params?: P, init: RequestInit = { }): Promise<Response> {
const reqInit: RequestInit = { ...init };
const { query } = params || {} as P;
if (!reqInit.method) {
reqInit.method = "get";
}
if (query) {
const queryString = stringify(query);
reqUrl += (reqUrl.includes("?") ? "&" : "?") + queryString;
}
const infoLog: JsonApiLog = {
method: `${reqInit.method.toUpperCase()} (stream)`,
reqUrl,
reqInit,
};
this.writeLog({ ...infoLog });
return fetch(reqUrl, reqInit);
}

View File

@ -371,12 +371,15 @@ export class KubeApi<T extends KubeObject = any> {
opts.abortController = new AbortController();
}
const { abortController, namespace, callback } = opts;
const watchUrl = this.getWatchUrl(namespace);
const responsePromise = this.request.getReadableStream(watchUrl, null, { signal: abortController.signal });
let disposed = false;
// FIXME
const watchUrl = `http://${this.kind}-watch.${window.location.host}${apiKubePrefix}${this.getWatchUrl(namespace)}`;
const responsePromise = this.request.getResponse(watchUrl, null, {
signal: abortController.signal
});
responsePromise.then((response) => {
if (!response.ok && !disposed) {
if (!response.ok && !abortController.signal.aborted) {
if (response.status === 410) { // resourceVersion has gone
setTimeout(() => {
this.refreshResourceVersion().then(() => {
@ -399,8 +402,6 @@ export class KubeApi<T extends KubeObject = any> {
try {
const data: IKubeWatchEvent = JSON.parse(line);
console.log("data", data);
if (callback) {
callback(data);
}
@ -411,7 +412,7 @@ export class KubeApi<T extends KubeObject = any> {
stream.on("close", () => {
setTimeout(() => {
if (!disposed) this.watch({...opts, namespace, callback});
if (!abortController.signal.aborted) this.watch({...opts, namespace, callback});
}, 1000);
});
}, (error) => {
@ -423,7 +424,6 @@ export class KubeApi<T extends KubeObject = any> {
});
const disposer = () => {
disposed = true;
abortController.abort();
};

View File

@ -22,6 +22,7 @@ import { MenuItem } from "../menu";
import { Checkbox } from "../checkbox";
import { userStore } from "../../../common/user-store";
import { namespaceStore } from "../+namespaces/namespace.store";
import { Icon } from "../icon";
// todo: refactor, split to small re-usable components
@ -341,16 +342,17 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
const allItemsCount = this.props.store.getTotalCount();
const itemsCount = items.length;
const isFiltered = isReady && filters.length > 0;
const RefreshIcon = <Icon material="update" small={true} onClick={() => this.loadStores()} />;
if (isFiltered) {
const toggleFilters = () => userSettings.showAppliedFilters = !userSettings.showAppliedFilters;
return (
<><a onClick={toggleFilters}>Filtered</a>: {itemsCount} / {allItemsCount}</>
<><a onClick={toggleFilters}>Filtered</a>: {itemsCount} / {allItemsCount} {RefreshIcon}</>
);
}
return allItemsCount <= 1 ? `${allItemsCount} item` : `${allItemsCount} items`;
return allItemsCount <= 1 ? <>{allItemsCount} item {RefreshIcon}</> : <>{allItemsCount} items {RefreshIcon}</>;
}
renderHeader() {

View File

@ -267,16 +267,16 @@ export abstract class KubeObjectStore<T extends KubeObject = any> extends ItemSt
}
subscribe(apis = this.getSubscribeApis()) {
const abortController = new AbortController();
let disposers: {(): void}[] = [];
const callback = (data: IKubeWatchEvent) => {
if (!this.isLoaded) return;
this.eventsBuffer.push(data);
};
if (this.context.cluster.isGlobalWatchEnabled) {
disposers = apis.map(api => api.watch({
abortController,
namespace: "",
callback: (data) => callback(data),
}));
@ -284,7 +284,6 @@ export abstract class KubeObjectStore<T extends KubeObject = any> extends ItemSt
apis.map(api => {
this.loadedNamespaces.forEach((namespace) => {
disposers.push(api.watch({
abortController,
namespace,
callback: (data) => callback(data)
}));