@dxos/edge-client 0.7.5-main.e9bb01b → 0.7.5-staging.2ff1350
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/index.mjs +162 -206
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +147 -189
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +162 -206
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/edge-client.d.ts.map +1 -1
- package/dist/types/src/edge-http-client.d.ts +6 -1
- package/dist/types/src/edge-http-client.d.ts.map +1 -1
- package/dist/types/src/edge-ws-connection.d.ts.map +1 -1
- package/package.json +15 -14
- package/src/edge-client.ts +1 -2
- package/src/edge-http-client.ts +88 -4
- package/src/edge-ws-connection.ts +6 -4
- package/dist/types/src/persistent-lifecycle.d.ts +0 -44
- package/dist/types/src/persistent-lifecycle.d.ts.map +0 -1
- package/dist/types/src/persistent-lifecycle.test.d.ts +0 -2
- package/dist/types/src/persistent-lifecycle.test.d.ts.map +0 -1
- package/src/persistent-lifecycle.test.ts +0 -71
- package/src/persistent-lifecycle.ts +0 -121
package/src/edge-http-client.ts
CHANGED
|
@@ -21,6 +21,10 @@ import {
|
|
|
21
21
|
type RecoverIdentityResponseBody,
|
|
22
22
|
type UploadFunctionRequest,
|
|
23
23
|
type UploadFunctionResponseBody,
|
|
24
|
+
type ObjectId,
|
|
25
|
+
type ExecuteWorkflowResponseBody,
|
|
26
|
+
type QueueQuery,
|
|
27
|
+
type QueryResult,
|
|
24
28
|
} from '@dxos/protocols';
|
|
25
29
|
|
|
26
30
|
import { type EdgeIdentity, handleAuthChallenge } from './edge-identity';
|
|
@@ -34,6 +38,7 @@ export class EdgeHttpClient {
|
|
|
34
38
|
private readonly _baseUrl: string;
|
|
35
39
|
|
|
36
40
|
private _edgeIdentity: EdgeIdentity | undefined;
|
|
41
|
+
|
|
37
42
|
/**
|
|
38
43
|
* Auth header is cached until receiving the next 401 from EDGE, at which point it gets refreshed.
|
|
39
44
|
*/
|
|
@@ -44,6 +49,10 @@ export class EdgeHttpClient {
|
|
|
44
49
|
log('created', { url: this._baseUrl });
|
|
45
50
|
}
|
|
46
51
|
|
|
52
|
+
get baseUrl() {
|
|
53
|
+
return this._baseUrl;
|
|
54
|
+
}
|
|
55
|
+
|
|
47
56
|
setIdentity(identity: EdgeIdentity) {
|
|
48
57
|
if (this._edgeIdentity?.identityKey !== identity.identityKey || this._edgeIdentity?.peerKey !== identity.peerKey) {
|
|
49
58
|
this._edgeIdentity = identity;
|
|
@@ -89,6 +98,15 @@ export class EdgeHttpClient {
|
|
|
89
98
|
return this._call('/identity/recover', { ...args, body, method: 'POST' });
|
|
90
99
|
}
|
|
91
100
|
|
|
101
|
+
public async executeWorkflow(
|
|
102
|
+
spaceId: SpaceId,
|
|
103
|
+
graphId: ObjectId,
|
|
104
|
+
input: any,
|
|
105
|
+
args?: EdgeHttpGetArgs,
|
|
106
|
+
): Promise<ExecuteWorkflowResponseBody> {
|
|
107
|
+
return this._call(`/workflows/${spaceId}/${graphId}`, { ...args, body: input, method: 'POST' });
|
|
108
|
+
}
|
|
109
|
+
|
|
92
110
|
public async uploadFunction(
|
|
93
111
|
pathParts: { spaceId: SpaceId; functionId?: string },
|
|
94
112
|
body: UploadFunctionRequest,
|
|
@@ -98,12 +116,77 @@ export class EdgeHttpClient {
|
|
|
98
116
|
return this._call(path, { ...args, body, method: 'PUT' });
|
|
99
117
|
}
|
|
100
118
|
|
|
119
|
+
public async queryQueue(
|
|
120
|
+
subspaceTag: string,
|
|
121
|
+
spaceId: SpaceId,
|
|
122
|
+
query: QueueQuery,
|
|
123
|
+
args?: EdgeHttpGetArgs,
|
|
124
|
+
): Promise<QueryResult> {
|
|
125
|
+
const { queueId } = query;
|
|
126
|
+
const queryParams = new URLSearchParams();
|
|
127
|
+
if (query.after != null) {
|
|
128
|
+
queryParams.set('after', query.after);
|
|
129
|
+
}
|
|
130
|
+
if (query.before != null) {
|
|
131
|
+
queryParams.set('before', query.before);
|
|
132
|
+
}
|
|
133
|
+
if (query.limit != null) {
|
|
134
|
+
queryParams.set('limit', query.limit.toString());
|
|
135
|
+
}
|
|
136
|
+
if (query.reverse != null) {
|
|
137
|
+
queryParams.set('reverse', query.reverse.toString());
|
|
138
|
+
}
|
|
139
|
+
if (query.objectIds != null) {
|
|
140
|
+
queryParams.set('objectIds', query.objectIds.join(','));
|
|
141
|
+
}
|
|
142
|
+
return this._call(`/spaces/${subspaceTag}/${spaceId}/queue/${queueId}/query?${queryParams.toString()}`, {
|
|
143
|
+
...args,
|
|
144
|
+
method: 'GET',
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
public async insertIntoQueue(
|
|
149
|
+
subspaceTag: string,
|
|
150
|
+
spaceId: SpaceId,
|
|
151
|
+
queueId: ObjectId,
|
|
152
|
+
objects: unknown[],
|
|
153
|
+
args?: EdgeHttpGetArgs,
|
|
154
|
+
): Promise<void> {
|
|
155
|
+
return this._call(`/spaces/${subspaceTag}/${spaceId}/queue/${queueId}`, {
|
|
156
|
+
...args,
|
|
157
|
+
body: { objects },
|
|
158
|
+
method: 'POST',
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async deleteFromQueue(
|
|
163
|
+
subspaceTag: string,
|
|
164
|
+
spaceId: SpaceId,
|
|
165
|
+
queueId: ObjectId,
|
|
166
|
+
objectIds: ObjectId[],
|
|
167
|
+
args?: EdgeHttpGetArgs,
|
|
168
|
+
): Promise<void> {
|
|
169
|
+
return this._call(`/spaces/${subspaceTag}/${spaceId}/queue/${queueId}`, {
|
|
170
|
+
...args,
|
|
171
|
+
query: { ids: objectIds.join(',') },
|
|
172
|
+
method: 'DELETE',
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
101
176
|
private async _call<T>(path: string, args: EdgeHttpCallArgs): Promise<T> {
|
|
102
177
|
const requestContext = args.context ?? new Context();
|
|
103
178
|
const shouldRetry = createRetryHandler(args);
|
|
104
|
-
|
|
179
|
+
let url = `${this._baseUrl}${path.startsWith('/') ? path.slice(1) : path}`;
|
|
180
|
+
|
|
181
|
+
if (args.query) {
|
|
182
|
+
const queryParams = new URLSearchParams();
|
|
183
|
+
for (const [key, value] of Object.entries(args.query)) {
|
|
184
|
+
queryParams.set(key, value.toString());
|
|
185
|
+
}
|
|
186
|
+
url += `?${queryParams.toString()}`;
|
|
187
|
+
}
|
|
105
188
|
|
|
106
|
-
log
|
|
189
|
+
log('call', { method: args.method, path, request: args.body });
|
|
107
190
|
|
|
108
191
|
let handledAuth = false;
|
|
109
192
|
let authHeader = this._authHeader;
|
|
@@ -122,7 +205,7 @@ export class EdgeHttpClient {
|
|
|
122
205
|
return body.data;
|
|
123
206
|
}
|
|
124
207
|
|
|
125
|
-
log
|
|
208
|
+
log('unsuccessful edge response', { path, body });
|
|
126
209
|
|
|
127
210
|
if (body.errorData?.type === 'auth_challenge' && typeof body.errorData?.challenge === 'string') {
|
|
128
211
|
processingError = new EdgeAuthChallengeError(body.errorData.challenge, body.errorData);
|
|
@@ -141,7 +224,7 @@ export class EdgeHttpClient {
|
|
|
141
224
|
}
|
|
142
225
|
|
|
143
226
|
if (processingError.isRetryable && (await shouldRetry(requestContext, retryAfterHeaderValue))) {
|
|
144
|
-
log
|
|
227
|
+
log('retrying edge request', { path, processingError });
|
|
145
228
|
} else {
|
|
146
229
|
throw processingError;
|
|
147
230
|
}
|
|
@@ -208,6 +291,7 @@ type EdgeHttpCallArgs = {
|
|
|
208
291
|
body?: any;
|
|
209
292
|
context?: Context;
|
|
210
293
|
retry?: RetryConfig;
|
|
294
|
+
query?: Record<string, string>;
|
|
211
295
|
};
|
|
212
296
|
|
|
213
297
|
const createRequest = (args: EdgeHttpCallArgs, authHeader: string | undefined): RequestInit => {
|
|
@@ -15,7 +15,8 @@ import { protocol } from './defs';
|
|
|
15
15
|
import { type EdgeIdentity } from './edge-identity';
|
|
16
16
|
import { toUint8Array } from './protocol';
|
|
17
17
|
|
|
18
|
-
const SIGNAL_KEEPALIVE_INTERVAL =
|
|
18
|
+
const SIGNAL_KEEPALIVE_INTERVAL = 4_000;
|
|
19
|
+
const SIGNAL_KEEPALIVE_TIMEOUT = 12_000;
|
|
19
20
|
|
|
20
21
|
/**
|
|
21
22
|
* 1MB websocket message limit: https://developers.cloudflare.com/durable-objects/platform/limits/
|
|
@@ -79,9 +80,9 @@ export class EdgeWsConnection extends Resource {
|
|
|
79
80
|
log.verbose('connected after becoming inactive', { currentIdentity: this._identity });
|
|
80
81
|
}
|
|
81
82
|
};
|
|
82
|
-
this._ws.onclose = () => {
|
|
83
|
+
this._ws.onclose = (event) => {
|
|
83
84
|
if (this.isOpen) {
|
|
84
|
-
log('disconnected while being open');
|
|
85
|
+
log.warn('disconnected while being open', { code: event.code, reason: event.reason });
|
|
85
86
|
this._callbacks.onRestartRequired();
|
|
86
87
|
}
|
|
87
88
|
};
|
|
@@ -153,10 +154,11 @@ export class EdgeWsConnection extends Resource {
|
|
|
153
154
|
this._inactivityTimeoutCtx,
|
|
154
155
|
() => {
|
|
155
156
|
if (this.isOpen) {
|
|
157
|
+
log.warn('restart due to inactivity timeout');
|
|
156
158
|
this._callbacks.onRestartRequired();
|
|
157
159
|
}
|
|
158
160
|
},
|
|
159
|
-
|
|
161
|
+
SIGNAL_KEEPALIVE_TIMEOUT,
|
|
160
162
|
);
|
|
161
163
|
}
|
|
162
164
|
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { Resource } from '@dxos/context';
|
|
2
|
-
export type PersistentLifecycleParams<T> = {
|
|
3
|
-
/**
|
|
4
|
-
* Create connection.
|
|
5
|
-
* If promise resolves successfully, connection is considered established.
|
|
6
|
-
*/
|
|
7
|
-
start: () => Promise<T | undefined>;
|
|
8
|
-
/**
|
|
9
|
-
* Reset connection to initial state.
|
|
10
|
-
*/
|
|
11
|
-
stop: (state: T) => Promise<void>;
|
|
12
|
-
/**
|
|
13
|
-
* Called after successful start.
|
|
14
|
-
*/
|
|
15
|
-
onRestart?: () => Promise<void>;
|
|
16
|
-
/**
|
|
17
|
-
* Maximum delay between restartion attempts.
|
|
18
|
-
* Default: 5000ms
|
|
19
|
-
*/
|
|
20
|
-
maxRestartDelay?: number;
|
|
21
|
-
};
|
|
22
|
-
/**
|
|
23
|
-
* Handles restarts (e.g. persists connection).
|
|
24
|
-
* Restarts are scheduled with exponential backoff.
|
|
25
|
-
*/
|
|
26
|
-
export declare class PersistentLifecycle<T> extends Resource {
|
|
27
|
-
private readonly _start;
|
|
28
|
-
private readonly _stop;
|
|
29
|
-
private readonly _onRestart?;
|
|
30
|
-
private readonly _maxRestartDelay;
|
|
31
|
-
private _currentContext;
|
|
32
|
-
private _restartTask?;
|
|
33
|
-
private _restartAfter;
|
|
34
|
-
constructor({ start, stop, onRestart, maxRestartDelay }: PersistentLifecycleParams<T>);
|
|
35
|
-
protected _open(): Promise<void>;
|
|
36
|
-
protected _close(): Promise<void>;
|
|
37
|
-
private _restart;
|
|
38
|
-
private _stopCurrentContext;
|
|
39
|
-
/**
|
|
40
|
-
* Scheduling restart should be done from outside.
|
|
41
|
-
*/
|
|
42
|
-
scheduleRestart(): void;
|
|
43
|
-
}
|
|
44
|
-
//# sourceMappingURL=persistent-lifecycle.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"persistent-lifecycle.d.ts","sourceRoot":"","sources":["../../../src/persistent-lifecycle.ts"],"names":[],"mappings":"AAKA,OAAO,EAAqC,QAAQ,EAAE,MAAM,eAAe,CAAC;AAO5E,MAAM,MAAM,yBAAyB,CAAC,CAAC,IAAI;IACzC;;;OAGG;IACH,KAAK,EAAE,MAAM,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAEpC;;OAEG;IACH,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAElC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhC;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF;;;GAGG;AACH,qBAAa,mBAAmB,CAAC,CAAC,CAAE,SAAQ,QAAQ;IAClD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA+B;IACtD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA8B;IACpD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAsB;IAClD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAE1C,OAAO,CAAC,eAAe,CAA4B;IACnD,OAAO,CAAC,YAAY,CAAC,CAA2B;IAChD,OAAO,CAAC,aAAa,CAAK;gBAEd,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,eAA2C,EAAE,EAAE,yBAAyB,CAAC,CAAC,CAAC;cASxF,KAAK;cAgBL,MAAM;YAMjB,QAAQ;YAkBR,mBAAmB;IAWjC;;OAEG;IAEH,eAAe;CAMhB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"persistent-lifecycle.test.d.ts","sourceRoot":"","sources":["../../../src/persistent-lifecycle.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2024 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { describe, expect, test } from 'vitest';
|
|
6
|
-
|
|
7
|
-
import { sleep, Trigger } from '@dxos/async';
|
|
8
|
-
import { log } from '@dxos/log';
|
|
9
|
-
import { openAndClose } from '@dxos/test-utils';
|
|
10
|
-
|
|
11
|
-
import { PersistentLifecycle } from './persistent-lifecycle';
|
|
12
|
-
|
|
13
|
-
describe('ConnectionState', () => {
|
|
14
|
-
test('first reconnect fires immediately', async () => {
|
|
15
|
-
const triggerCall = new Trigger<number>();
|
|
16
|
-
const persistentLifecycle = new PersistentLifecycle({
|
|
17
|
-
start: async () => {
|
|
18
|
-
triggerCall.wake(Date.now());
|
|
19
|
-
},
|
|
20
|
-
stop: async () => {},
|
|
21
|
-
});
|
|
22
|
-
await openAndClose(persistentLifecycle);
|
|
23
|
-
|
|
24
|
-
const triggerTimestamp = Date.now();
|
|
25
|
-
persistentLifecycle.scheduleRestart();
|
|
26
|
-
const timeToTrigger = (await triggerCall.wait({ timeout: 1000 })) - triggerTimestamp;
|
|
27
|
-
expect(timeToTrigger).to.be.lessThan(50);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
test('second reconnect fires after 100ms', async () => {
|
|
31
|
-
let called = 0;
|
|
32
|
-
const triggerCall = new Trigger<number>();
|
|
33
|
-
|
|
34
|
-
const persistentLifecycle = new PersistentLifecycle({
|
|
35
|
-
start: async () => {
|
|
36
|
-
called += 1;
|
|
37
|
-
log.info('called', { called });
|
|
38
|
-
if (called < 3) {
|
|
39
|
-
throw new Error('TEST ERROR');
|
|
40
|
-
}
|
|
41
|
-
triggerCall.wake(Date.now());
|
|
42
|
-
},
|
|
43
|
-
stop: async () => {},
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
await openAndClose(persistentLifecycle);
|
|
47
|
-
|
|
48
|
-
const triggerTimestamp = Date.now();
|
|
49
|
-
await sleep(10);
|
|
50
|
-
const timeToTrigger = (await triggerCall.wait({ timeout: 1000 })) - triggerTimestamp;
|
|
51
|
-
expect(timeToTrigger).to.be.greaterThanOrEqual(100);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
test('finish `restart` before close', async () => {
|
|
55
|
-
let restarted = false;
|
|
56
|
-
const persistentLifecycle = new PersistentLifecycle({
|
|
57
|
-
start: async () => await sleep(100),
|
|
58
|
-
stop: async () => {},
|
|
59
|
-
onRestart: async () => {
|
|
60
|
-
restarted = true;
|
|
61
|
-
},
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
await persistentLifecycle.open();
|
|
65
|
-
|
|
66
|
-
persistentLifecycle.scheduleRestart();
|
|
67
|
-
await sleep(10);
|
|
68
|
-
await persistentLifecycle.close();
|
|
69
|
-
expect(restarted).to.be.true;
|
|
70
|
-
});
|
|
71
|
-
});
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2024 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { DeferredTask, sleep, synchronized } from '@dxos/async';
|
|
6
|
-
import { cancelWithContext, LifecycleState, Resource } from '@dxos/context';
|
|
7
|
-
import { warnAfterTimeout } from '@dxos/debug';
|
|
8
|
-
import { log } from '@dxos/log';
|
|
9
|
-
|
|
10
|
-
const INIT_RESTART_DELAY = 100;
|
|
11
|
-
const DEFAULT_MAX_RESTART_DELAY = 5000;
|
|
12
|
-
|
|
13
|
-
export type PersistentLifecycleParams<T> = {
|
|
14
|
-
/**
|
|
15
|
-
* Create connection.
|
|
16
|
-
* If promise resolves successfully, connection is considered established.
|
|
17
|
-
*/
|
|
18
|
-
start: () => Promise<T | undefined>;
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Reset connection to initial state.
|
|
22
|
-
*/
|
|
23
|
-
stop: (state: T) => Promise<void>;
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Called after successful start.
|
|
27
|
-
*/
|
|
28
|
-
onRestart?: () => Promise<void>;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Maximum delay between restartion attempts.
|
|
32
|
-
* Default: 5000ms
|
|
33
|
-
*/
|
|
34
|
-
maxRestartDelay?: number;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Handles restarts (e.g. persists connection).
|
|
39
|
-
* Restarts are scheduled with exponential backoff.
|
|
40
|
-
*/
|
|
41
|
-
export class PersistentLifecycle<T> extends Resource {
|
|
42
|
-
private readonly _start: () => Promise<T | undefined>;
|
|
43
|
-
private readonly _stop: (state: T) => Promise<void>;
|
|
44
|
-
private readonly _onRestart?: () => Promise<void>;
|
|
45
|
-
private readonly _maxRestartDelay: number;
|
|
46
|
-
|
|
47
|
-
private _currentContext: T | undefined = undefined;
|
|
48
|
-
private _restartTask?: DeferredTask = undefined;
|
|
49
|
-
private _restartAfter = 0;
|
|
50
|
-
|
|
51
|
-
constructor({ start, stop, onRestart, maxRestartDelay = DEFAULT_MAX_RESTART_DELAY }: PersistentLifecycleParams<T>) {
|
|
52
|
-
super();
|
|
53
|
-
this._start = start;
|
|
54
|
-
this._stop = stop;
|
|
55
|
-
this._onRestart = onRestart;
|
|
56
|
-
this._maxRestartDelay = maxRestartDelay;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
@synchronized
|
|
60
|
-
protected override async _open() {
|
|
61
|
-
this._restartTask = new DeferredTask(this._ctx, async () => {
|
|
62
|
-
try {
|
|
63
|
-
await this._restart();
|
|
64
|
-
} catch (err) {
|
|
65
|
-
log.warn('Restart failed', { err });
|
|
66
|
-
this._restartTask?.schedule();
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
this._currentContext = await this._start().catch((err) => {
|
|
70
|
-
log.warn('Start failed', { err });
|
|
71
|
-
this._restartTask?.schedule();
|
|
72
|
-
return undefined;
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
protected override async _close() {
|
|
77
|
-
await this._restartTask?.join();
|
|
78
|
-
await this._stopCurrentContext();
|
|
79
|
-
this._restartTask = undefined;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
private async _restart() {
|
|
83
|
-
log(`restarting in ${this._restartAfter}ms`, { state: this._lifecycleState });
|
|
84
|
-
await this._stopCurrentContext();
|
|
85
|
-
if (this._lifecycleState !== LifecycleState.OPEN) {
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
await cancelWithContext(this._ctx!, sleep(this._restartAfter));
|
|
89
|
-
this._restartAfter = Math.min(Math.max(this._restartAfter * 2, INIT_RESTART_DELAY), this._maxRestartDelay);
|
|
90
|
-
|
|
91
|
-
// May fail if the connection is not established.
|
|
92
|
-
await warnAfterTimeout(5_000, 'Connection establishment takes too long', async () => {
|
|
93
|
-
this._currentContext = await this._start();
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
this._restartAfter = 0;
|
|
97
|
-
await this._onRestart?.();
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
private async _stopCurrentContext() {
|
|
101
|
-
if (this._currentContext) {
|
|
102
|
-
try {
|
|
103
|
-
await this._stop(this._currentContext);
|
|
104
|
-
} catch (err) {
|
|
105
|
-
log.catch(err);
|
|
106
|
-
}
|
|
107
|
-
this._currentContext = undefined;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Scheduling restart should be done from outside.
|
|
113
|
-
*/
|
|
114
|
-
@synchronized
|
|
115
|
-
scheduleRestart() {
|
|
116
|
-
if (this._lifecycleState !== LifecycleState.OPEN) {
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
this._restartTask!.schedule();
|
|
120
|
-
}
|
|
121
|
-
}
|