@dronedeploy/rocos-js-sdk 4.4.7 → 4.4.8
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/cjs/api/StreamRegister.d.ts +7 -2
- package/cjs/api/StreamRegister.js +17 -2
- package/cjs/api/streams/telemetry/TelemetryStreamAbstract.d.ts +4 -0
- package/cjs/api/streams/telemetry/TelemetryStreamAbstract.js +42 -15
- package/cjs/services/TelemetryService.js +4 -2
- package/esm/api/StreamRegister.d.ts +7 -2
- package/esm/api/StreamRegister.js +17 -2
- package/esm/api/streams/telemetry/TelemetryStreamAbstract.d.ts +4 -0
- package/esm/api/streams/telemetry/TelemetryStreamAbstract.js +42 -15
- package/esm/services/TelemetryService.js +4 -2
- package/package.json +1 -1
|
@@ -10,8 +10,12 @@ export interface IAcquiredStream<T extends IBaseStream> {
|
|
|
10
10
|
/**
|
|
11
11
|
* Sole owner of stream lifecycle. Streams are shared per identifier and refcounted: acquireStream
|
|
12
12
|
* gets-or-creates and increments in one synchronous step, and the returned handle's release()
|
|
13
|
-
* tears the stream down when the last holder leaves.
|
|
14
|
-
*
|
|
13
|
+
* tears the stream down when the last holder leaves.
|
|
14
|
+
*
|
|
15
|
+
* A held stream can also be stopped and replaced underneath its holders, by reportStreamDead, when
|
|
16
|
+
* the stream can no longer carry anything. Holders keep the instance they were handed; their
|
|
17
|
+
* release() finds the entry gone and does nothing, so a replacement never inherits a departing
|
|
18
|
+
* holder's refcount and a refcount can not go negative.
|
|
15
19
|
*/
|
|
16
20
|
export declare class StreamRegister {
|
|
17
21
|
private entries;
|
|
@@ -22,6 +26,7 @@ export declare class StreamRegister {
|
|
|
22
26
|
static getIdentifier($identifier: string, scope?: string): string;
|
|
23
27
|
acquireStream<T extends IBaseStream>(identifier: string, create: () => T, init: (stream: T) => Promise<void>): IAcquiredStream<T>;
|
|
24
28
|
getStream(identifier: string): IBaseStream | undefined;
|
|
29
|
+
reportStreamDead(identifier: string, stream: IBaseStream): void;
|
|
25
30
|
removeAllStreams(): boolean;
|
|
26
31
|
private release;
|
|
27
32
|
private evict;
|
|
@@ -6,8 +6,12 @@ const RocosLogger_1 = require("../logger/RocosLogger");
|
|
|
6
6
|
/**
|
|
7
7
|
* Sole owner of stream lifecycle. Streams are shared per identifier and refcounted: acquireStream
|
|
8
8
|
* gets-or-creates and increments in one synchronous step, and the returned handle's release()
|
|
9
|
-
* tears the stream down when the last holder leaves.
|
|
10
|
-
*
|
|
9
|
+
* tears the stream down when the last holder leaves.
|
|
10
|
+
*
|
|
11
|
+
* A held stream can also be stopped and replaced underneath its holders, by reportStreamDead, when
|
|
12
|
+
* the stream can no longer carry anything. Holders keep the instance they were handed; their
|
|
13
|
+
* release() finds the entry gone and does nothing, so a replacement never inherits a departing
|
|
14
|
+
* holder's refcount and a refcount can not go negative.
|
|
11
15
|
*/
|
|
12
16
|
class StreamRegister {
|
|
13
17
|
constructor() {
|
|
@@ -62,6 +66,17 @@ class StreamRegister {
|
|
|
62
66
|
getStream(identifier) {
|
|
63
67
|
return this.entries.get(identifier)?.stream;
|
|
64
68
|
}
|
|
69
|
+
reportStreamDead(identifier, stream) {
|
|
70
|
+
if (this.entries.get(identifier)?.stream !== stream)
|
|
71
|
+
return; // already evicted, or already replaced
|
|
72
|
+
this.logger.warn(`Stream reported dead, evicting so the next acquirer builds a new one. identifier: ${identifier}`);
|
|
73
|
+
try {
|
|
74
|
+
this.evict(identifier, stream);
|
|
75
|
+
}
|
|
76
|
+
catch (e) {
|
|
77
|
+
this.logger.error(`Failed to evict dead stream. identifier: ${identifier}`, e);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
65
80
|
removeAllStreams() {
|
|
66
81
|
for (const [, entry] of this.entries.entries()) {
|
|
67
82
|
try {
|
|
@@ -29,6 +29,7 @@ export declare abstract class TelemetryStreamAbstract implements ITelemetryStrea
|
|
|
29
29
|
private sendHeartbeatTime;
|
|
30
30
|
private receivedDataStats;
|
|
31
31
|
private subscriptions;
|
|
32
|
+
private receiverDead;
|
|
32
33
|
constructor(config: ITelemetryStreamConfig);
|
|
33
34
|
protected abstract stopInternal(): void;
|
|
34
35
|
protected abstract registerReceiver(): () => void;
|
|
@@ -41,6 +42,8 @@ export declare abstract class TelemetryStreamAbstract implements ITelemetryStrea
|
|
|
41
42
|
stopStream(): void;
|
|
42
43
|
addSubscription(params: ITelemetryParams): void;
|
|
43
44
|
removeSubscription(params: ITelemetryParams, terminateReceiverGroup?: boolean): Promise<void>;
|
|
45
|
+
private onBackgroundActionFailure;
|
|
46
|
+
private markReceiverDead;
|
|
44
47
|
private isQueryLookup;
|
|
45
48
|
private getSubscribedSources;
|
|
46
49
|
sendAcknowledgment(uid: string, status: TelemetryAckStatus, noRetry: boolean): boolean;
|
|
@@ -55,6 +58,7 @@ export declare abstract class TelemetryStreamAbstract implements ITelemetryStrea
|
|
|
55
58
|
private takeTelemetryAction;
|
|
56
59
|
protected listenMessagesAndRenew(): void;
|
|
57
60
|
private addTerminateToAction;
|
|
61
|
+
private renewReceiver;
|
|
58
62
|
private messageTimeoutTryAgain;
|
|
59
63
|
/**
|
|
60
64
|
* Auto resubscribe to reduce CPU usage.
|
|
@@ -20,6 +20,14 @@ const resolveTelemetryActions = (actions) => {
|
|
|
20
20
|
const resolveUnsentTelemetryActions = (queueState) => {
|
|
21
21
|
resolveTelemetryActions(queueState.pendingActions.splice(0));
|
|
22
22
|
};
|
|
23
|
+
const isReceiverGoneError = (error) => {
|
|
24
|
+
const code = error?.code;
|
|
25
|
+
if (typeof code === 'number')
|
|
26
|
+
return code === 9; // gRPC FAILED_PRECONDITION
|
|
27
|
+
if (typeof code === 'string')
|
|
28
|
+
return code.toLowerCase() === 'failed_precondition';
|
|
29
|
+
return false;
|
|
30
|
+
};
|
|
23
31
|
const takeNextTelemetryBatch = (queueState) => {
|
|
24
32
|
const firstAction = queueState.pendingActions.shift();
|
|
25
33
|
if (!firstAction)
|
|
@@ -53,6 +61,7 @@ class TelemetryStreamAbstract {
|
|
|
53
61
|
this.sendHeartbeatTime = 5000;
|
|
54
62
|
this.receivedDataStats = {};
|
|
55
63
|
this.subscriptions = new Map();
|
|
64
|
+
this.receiverDead = false;
|
|
56
65
|
this.identifier = StreamRegister_1.StreamRegister.getIdentifier(identifier_1.IDENTIFIER_NAME_TELEMETRY, config.scope);
|
|
57
66
|
this.projectId = config.projectId;
|
|
58
67
|
this.callsignsLookup = config.callsignsLookup;
|
|
@@ -129,7 +138,7 @@ class TelemetryStreamAbstract {
|
|
|
129
138
|
if (toAdd.length) {
|
|
130
139
|
this.logger.debug('New query subscriptions added, we need to refresh sources', { toAdd });
|
|
131
140
|
void this.enqueueTelemetryAction('subscribe', this.callsignsLookup, toAdd).catch((error) => {
|
|
132
|
-
this.
|
|
141
|
+
this.onBackgroundActionFailure('subscribe', error);
|
|
133
142
|
});
|
|
134
143
|
}
|
|
135
144
|
}
|
|
@@ -142,7 +151,7 @@ class TelemetryStreamAbstract {
|
|
|
142
151
|
if (toAdd.callsigns.length && toAdd.sources.length) {
|
|
143
152
|
this.logger.debug('New subscriptions added, we need to refresh sources', { toAdd });
|
|
144
153
|
void this.enqueueTelemetryAction('subscribe', new models_1.CallsignsLookup(toAdd.callsigns), toAdd.sources).catch((error) => {
|
|
145
|
-
this.
|
|
154
|
+
this.onBackgroundActionFailure('subscribe', error);
|
|
146
155
|
});
|
|
147
156
|
}
|
|
148
157
|
}
|
|
@@ -178,7 +187,7 @@ class TelemetryStreamAbstract {
|
|
|
178
187
|
await this.enqueueTelemetryAction('unsubscribe', this.callsignsLookup, toRemove, terminateReceiverGroup);
|
|
179
188
|
}
|
|
180
189
|
catch (err) {
|
|
181
|
-
this.
|
|
190
|
+
this.onBackgroundActionFailure('unsubscribe', err);
|
|
182
191
|
}
|
|
183
192
|
}
|
|
184
193
|
return;
|
|
@@ -193,10 +202,24 @@ class TelemetryStreamAbstract {
|
|
|
193
202
|
await this.enqueueTelemetryAction('unsubscribe', new models_1.CallsignsLookup(toRemove.callsigns), toRemove.sources, terminateReceiverGroup);
|
|
194
203
|
}
|
|
195
204
|
catch (err) {
|
|
196
|
-
this.
|
|
205
|
+
this.onBackgroundActionFailure('unsubscribe', err);
|
|
197
206
|
}
|
|
198
207
|
}
|
|
199
208
|
}
|
|
209
|
+
onBackgroundActionFailure(actionType, error) {
|
|
210
|
+
this.logger.error(`Failed to ${actionType}: ${error}`);
|
|
211
|
+
if (isReceiverGoneError(error)) {
|
|
212
|
+
this.markReceiverDead(error);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
markReceiverDead(error) {
|
|
216
|
+
if (this.receiverDead)
|
|
217
|
+
return;
|
|
218
|
+
this.receiverDead = true;
|
|
219
|
+
this.logger.error('Receiver is no longer registered with the gateway, retiring the stream', error);
|
|
220
|
+
StreamRegister_1.StreamRegister.getInstance().reportStreamDead(this.identifier, this);
|
|
221
|
+
this.messageStream$.error(error);
|
|
222
|
+
}
|
|
200
223
|
isQueryLookup() {
|
|
201
224
|
return this.callsignsLookup?.isQuery() ?? false;
|
|
202
225
|
}
|
|
@@ -263,7 +286,7 @@ class TelemetryStreamAbstract {
|
|
|
263
286
|
rocosMessage.subscriberId = this.subscriberId;
|
|
264
287
|
this.logger.info('onData', `subscriberId has been updated - ${subscriberId}`, { subscriberId });
|
|
265
288
|
void this.enqueueTelemetryAction('subscribe').catch((error) => {
|
|
266
|
-
this.
|
|
289
|
+
this.onBackgroundActionFailure('subscribe', error);
|
|
267
290
|
});
|
|
268
291
|
this.heartbeat.start(() => this.sendHeartbeat(), this.sendHeartbeatTime);
|
|
269
292
|
isRobotMessage = false;
|
|
@@ -514,14 +537,22 @@ class TelemetryStreamAbstract {
|
|
|
514
537
|
unsubscribeOperation,
|
|
515
538
|
};
|
|
516
539
|
}
|
|
540
|
+
renewReceiver() {
|
|
541
|
+
try {
|
|
542
|
+
// Remove the received call anyway.
|
|
543
|
+
this.stopInternal();
|
|
544
|
+
this.lastMessageReceived = undefined;
|
|
545
|
+
this.lastRobotMessageReceived = undefined;
|
|
546
|
+
this.registerReceiver();
|
|
547
|
+
}
|
|
548
|
+
catch (e) {
|
|
549
|
+
this.logger.error('Failed to renew the receiver, retrying on the next check', e);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
517
552
|
messageTimeoutTryAgain() {
|
|
518
553
|
// Increase retry times.
|
|
519
554
|
this.retryTimes++;
|
|
520
|
-
|
|
521
|
-
this.stopInternal();
|
|
522
|
-
this.lastMessageReceived = undefined;
|
|
523
|
-
this.lastRobotMessageReceived = undefined;
|
|
524
|
-
this.registerReceiver();
|
|
555
|
+
this.renewReceiver();
|
|
525
556
|
}
|
|
526
557
|
/**
|
|
527
558
|
* Auto resubscribe to reduce CPU usage.
|
|
@@ -529,11 +560,7 @@ class TelemetryStreamAbstract {
|
|
|
529
560
|
autoResubscribe() {
|
|
530
561
|
// Reset
|
|
531
562
|
this.retryTimes = 0;
|
|
532
|
-
|
|
533
|
-
this.stopInternal();
|
|
534
|
-
this.lastMessageReceived = undefined;
|
|
535
|
-
this.lastRobotMessageReceived = undefined;
|
|
536
|
-
this.registerReceiver();
|
|
563
|
+
this.renewReceiver();
|
|
537
564
|
}
|
|
538
565
|
isFoundSource(source) {
|
|
539
566
|
return this.sources.indexOf(source) !== -1;
|
|
@@ -90,11 +90,13 @@ class TelemetryService extends BaseStreamService_1.BaseStreamService {
|
|
|
90
90
|
}), (0, operators_1.finalize)(() => {
|
|
91
91
|
if (params.terminateReceiverGroupOnUnsubscribe) {
|
|
92
92
|
const removal = stream.removeSubscription(subscriptionParams, true);
|
|
93
|
-
void Promise.resolve(removal)
|
|
93
|
+
void Promise.resolve(removal)
|
|
94
|
+
.finally(release)
|
|
95
|
+
.catch(() => undefined);
|
|
94
96
|
}
|
|
95
97
|
else {
|
|
96
98
|
release();
|
|
97
|
-
void stream.removeSubscription(subscriptionParams);
|
|
99
|
+
void Promise.resolve(stream.removeSubscription(subscriptionParams)).catch(() => undefined);
|
|
98
100
|
}
|
|
99
101
|
}));
|
|
100
102
|
});
|
|
@@ -10,8 +10,12 @@ export interface IAcquiredStream<T extends IBaseStream> {
|
|
|
10
10
|
/**
|
|
11
11
|
* Sole owner of stream lifecycle. Streams are shared per identifier and refcounted: acquireStream
|
|
12
12
|
* gets-or-creates and increments in one synchronous step, and the returned handle's release()
|
|
13
|
-
* tears the stream down when the last holder leaves.
|
|
14
|
-
*
|
|
13
|
+
* tears the stream down when the last holder leaves.
|
|
14
|
+
*
|
|
15
|
+
* A held stream can also be stopped and replaced underneath its holders, by reportStreamDead, when
|
|
16
|
+
* the stream can no longer carry anything. Holders keep the instance they were handed; their
|
|
17
|
+
* release() finds the entry gone and does nothing, so a replacement never inherits a departing
|
|
18
|
+
* holder's refcount and a refcount can not go negative.
|
|
15
19
|
*/
|
|
16
20
|
export declare class StreamRegister {
|
|
17
21
|
private entries;
|
|
@@ -22,6 +26,7 @@ export declare class StreamRegister {
|
|
|
22
26
|
static getIdentifier($identifier: string, scope?: string): string;
|
|
23
27
|
acquireStream<T extends IBaseStream>(identifier: string, create: () => T, init: (stream: T) => Promise<void>): IAcquiredStream<T>;
|
|
24
28
|
getStream(identifier: string): IBaseStream | undefined;
|
|
29
|
+
reportStreamDead(identifier: string, stream: IBaseStream): void;
|
|
25
30
|
removeAllStreams(): boolean;
|
|
26
31
|
private release;
|
|
27
32
|
private evict;
|
|
@@ -3,8 +3,12 @@ import { RocosLogger } from '../logger/RocosLogger';
|
|
|
3
3
|
/**
|
|
4
4
|
* Sole owner of stream lifecycle. Streams are shared per identifier and refcounted: acquireStream
|
|
5
5
|
* gets-or-creates and increments in one synchronous step, and the returned handle's release()
|
|
6
|
-
* tears the stream down when the last holder leaves.
|
|
7
|
-
*
|
|
6
|
+
* tears the stream down when the last holder leaves.
|
|
7
|
+
*
|
|
8
|
+
* A held stream can also be stopped and replaced underneath its holders, by reportStreamDead, when
|
|
9
|
+
* the stream can no longer carry anything. Holders keep the instance they were handed; their
|
|
10
|
+
* release() finds the entry gone and does nothing, so a replacement never inherits a departing
|
|
11
|
+
* holder's refcount and a refcount can not go negative.
|
|
8
12
|
*/
|
|
9
13
|
export class StreamRegister {
|
|
10
14
|
constructor() {
|
|
@@ -59,6 +63,17 @@ export class StreamRegister {
|
|
|
59
63
|
getStream(identifier) {
|
|
60
64
|
return this.entries.get(identifier)?.stream;
|
|
61
65
|
}
|
|
66
|
+
reportStreamDead(identifier, stream) {
|
|
67
|
+
if (this.entries.get(identifier)?.stream !== stream)
|
|
68
|
+
return; // already evicted, or already replaced
|
|
69
|
+
this.logger.warn(`Stream reported dead, evicting so the next acquirer builds a new one. identifier: ${identifier}`);
|
|
70
|
+
try {
|
|
71
|
+
this.evict(identifier, stream);
|
|
72
|
+
}
|
|
73
|
+
catch (e) {
|
|
74
|
+
this.logger.error(`Failed to evict dead stream. identifier: ${identifier}`, e);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
62
77
|
removeAllStreams() {
|
|
63
78
|
for (const [, entry] of this.entries.entries()) {
|
|
64
79
|
try {
|
|
@@ -29,6 +29,7 @@ export declare abstract class TelemetryStreamAbstract implements ITelemetryStrea
|
|
|
29
29
|
private sendHeartbeatTime;
|
|
30
30
|
private receivedDataStats;
|
|
31
31
|
private subscriptions;
|
|
32
|
+
private receiverDead;
|
|
32
33
|
constructor(config: ITelemetryStreamConfig);
|
|
33
34
|
protected abstract stopInternal(): void;
|
|
34
35
|
protected abstract registerReceiver(): () => void;
|
|
@@ -41,6 +42,8 @@ export declare abstract class TelemetryStreamAbstract implements ITelemetryStrea
|
|
|
41
42
|
stopStream(): void;
|
|
42
43
|
addSubscription(params: ITelemetryParams): void;
|
|
43
44
|
removeSubscription(params: ITelemetryParams, terminateReceiverGroup?: boolean): Promise<void>;
|
|
45
|
+
private onBackgroundActionFailure;
|
|
46
|
+
private markReceiverDead;
|
|
44
47
|
private isQueryLookup;
|
|
45
48
|
private getSubscribedSources;
|
|
46
49
|
sendAcknowledgment(uid: string, status: TelemetryAckStatus, noRetry: boolean): boolean;
|
|
@@ -55,6 +58,7 @@ export declare abstract class TelemetryStreamAbstract implements ITelemetryStrea
|
|
|
55
58
|
private takeTelemetryAction;
|
|
56
59
|
protected listenMessagesAndRenew(): void;
|
|
57
60
|
private addTerminateToAction;
|
|
61
|
+
private renewReceiver;
|
|
58
62
|
private messageTimeoutTryAgain;
|
|
59
63
|
/**
|
|
60
64
|
* Auto resubscribe to reduce CPU usage.
|
|
@@ -17,6 +17,14 @@ const resolveTelemetryActions = (actions) => {
|
|
|
17
17
|
const resolveUnsentTelemetryActions = (queueState) => {
|
|
18
18
|
resolveTelemetryActions(queueState.pendingActions.splice(0));
|
|
19
19
|
};
|
|
20
|
+
const isReceiverGoneError = (error) => {
|
|
21
|
+
const code = error?.code;
|
|
22
|
+
if (typeof code === 'number')
|
|
23
|
+
return code === 9; // gRPC FAILED_PRECONDITION
|
|
24
|
+
if (typeof code === 'string')
|
|
25
|
+
return code.toLowerCase() === 'failed_precondition';
|
|
26
|
+
return false;
|
|
27
|
+
};
|
|
20
28
|
const takeNextTelemetryBatch = (queueState) => {
|
|
21
29
|
const firstAction = queueState.pendingActions.shift();
|
|
22
30
|
if (!firstAction)
|
|
@@ -50,6 +58,7 @@ export class TelemetryStreamAbstract {
|
|
|
50
58
|
this.sendHeartbeatTime = 5000;
|
|
51
59
|
this.receivedDataStats = {};
|
|
52
60
|
this.subscriptions = new Map();
|
|
61
|
+
this.receiverDead = false;
|
|
53
62
|
this.identifier = StreamRegister.getIdentifier(IDENTIFIER_NAME_TELEMETRY, config.scope);
|
|
54
63
|
this.projectId = config.projectId;
|
|
55
64
|
this.callsignsLookup = config.callsignsLookup;
|
|
@@ -126,7 +135,7 @@ export class TelemetryStreamAbstract {
|
|
|
126
135
|
if (toAdd.length) {
|
|
127
136
|
this.logger.debug('New query subscriptions added, we need to refresh sources', { toAdd });
|
|
128
137
|
void this.enqueueTelemetryAction('subscribe', this.callsignsLookup, toAdd).catch((error) => {
|
|
129
|
-
this.
|
|
138
|
+
this.onBackgroundActionFailure('subscribe', error);
|
|
130
139
|
});
|
|
131
140
|
}
|
|
132
141
|
}
|
|
@@ -139,7 +148,7 @@ export class TelemetryStreamAbstract {
|
|
|
139
148
|
if (toAdd.callsigns.length && toAdd.sources.length) {
|
|
140
149
|
this.logger.debug('New subscriptions added, we need to refresh sources', { toAdd });
|
|
141
150
|
void this.enqueueTelemetryAction('subscribe', new CallsignsLookup(toAdd.callsigns), toAdd.sources).catch((error) => {
|
|
142
|
-
this.
|
|
151
|
+
this.onBackgroundActionFailure('subscribe', error);
|
|
143
152
|
});
|
|
144
153
|
}
|
|
145
154
|
}
|
|
@@ -175,7 +184,7 @@ export class TelemetryStreamAbstract {
|
|
|
175
184
|
await this.enqueueTelemetryAction('unsubscribe', this.callsignsLookup, toRemove, terminateReceiverGroup);
|
|
176
185
|
}
|
|
177
186
|
catch (err) {
|
|
178
|
-
this.
|
|
187
|
+
this.onBackgroundActionFailure('unsubscribe', err);
|
|
179
188
|
}
|
|
180
189
|
}
|
|
181
190
|
return;
|
|
@@ -190,10 +199,24 @@ export class TelemetryStreamAbstract {
|
|
|
190
199
|
await this.enqueueTelemetryAction('unsubscribe', new CallsignsLookup(toRemove.callsigns), toRemove.sources, terminateReceiverGroup);
|
|
191
200
|
}
|
|
192
201
|
catch (err) {
|
|
193
|
-
this.
|
|
202
|
+
this.onBackgroundActionFailure('unsubscribe', err);
|
|
194
203
|
}
|
|
195
204
|
}
|
|
196
205
|
}
|
|
206
|
+
onBackgroundActionFailure(actionType, error) {
|
|
207
|
+
this.logger.error(`Failed to ${actionType}: ${error}`);
|
|
208
|
+
if (isReceiverGoneError(error)) {
|
|
209
|
+
this.markReceiverDead(error);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
markReceiverDead(error) {
|
|
213
|
+
if (this.receiverDead)
|
|
214
|
+
return;
|
|
215
|
+
this.receiverDead = true;
|
|
216
|
+
this.logger.error('Receiver is no longer registered with the gateway, retiring the stream', error);
|
|
217
|
+
StreamRegister.getInstance().reportStreamDead(this.identifier, this);
|
|
218
|
+
this.messageStream$.error(error);
|
|
219
|
+
}
|
|
197
220
|
isQueryLookup() {
|
|
198
221
|
return this.callsignsLookup?.isQuery() ?? false;
|
|
199
222
|
}
|
|
@@ -260,7 +283,7 @@ export class TelemetryStreamAbstract {
|
|
|
260
283
|
rocosMessage.subscriberId = this.subscriberId;
|
|
261
284
|
this.logger.info('onData', `subscriberId has been updated - ${subscriberId}`, { subscriberId });
|
|
262
285
|
void this.enqueueTelemetryAction('subscribe').catch((error) => {
|
|
263
|
-
this.
|
|
286
|
+
this.onBackgroundActionFailure('subscribe', error);
|
|
264
287
|
});
|
|
265
288
|
this.heartbeat.start(() => this.sendHeartbeat(), this.sendHeartbeatTime);
|
|
266
289
|
isRobotMessage = false;
|
|
@@ -511,14 +534,22 @@ export class TelemetryStreamAbstract {
|
|
|
511
534
|
unsubscribeOperation,
|
|
512
535
|
};
|
|
513
536
|
}
|
|
537
|
+
renewReceiver() {
|
|
538
|
+
try {
|
|
539
|
+
// Remove the received call anyway.
|
|
540
|
+
this.stopInternal();
|
|
541
|
+
this.lastMessageReceived = undefined;
|
|
542
|
+
this.lastRobotMessageReceived = undefined;
|
|
543
|
+
this.registerReceiver();
|
|
544
|
+
}
|
|
545
|
+
catch (e) {
|
|
546
|
+
this.logger.error('Failed to renew the receiver, retrying on the next check', e);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
514
549
|
messageTimeoutTryAgain() {
|
|
515
550
|
// Increase retry times.
|
|
516
551
|
this.retryTimes++;
|
|
517
|
-
|
|
518
|
-
this.stopInternal();
|
|
519
|
-
this.lastMessageReceived = undefined;
|
|
520
|
-
this.lastRobotMessageReceived = undefined;
|
|
521
|
-
this.registerReceiver();
|
|
552
|
+
this.renewReceiver();
|
|
522
553
|
}
|
|
523
554
|
/**
|
|
524
555
|
* Auto resubscribe to reduce CPU usage.
|
|
@@ -526,11 +557,7 @@ export class TelemetryStreamAbstract {
|
|
|
526
557
|
autoResubscribe() {
|
|
527
558
|
// Reset
|
|
528
559
|
this.retryTimes = 0;
|
|
529
|
-
|
|
530
|
-
this.stopInternal();
|
|
531
|
-
this.lastMessageReceived = undefined;
|
|
532
|
-
this.lastRobotMessageReceived = undefined;
|
|
533
|
-
this.registerReceiver();
|
|
560
|
+
this.renewReceiver();
|
|
534
561
|
}
|
|
535
562
|
isFoundSource(source) {
|
|
536
563
|
return this.sources.indexOf(source) !== -1;
|
|
@@ -87,11 +87,13 @@ export class TelemetryService extends BaseStreamService {
|
|
|
87
87
|
}), finalize(() => {
|
|
88
88
|
if (params.terminateReceiverGroupOnUnsubscribe) {
|
|
89
89
|
const removal = stream.removeSubscription(subscriptionParams, true);
|
|
90
|
-
void Promise.resolve(removal)
|
|
90
|
+
void Promise.resolve(removal)
|
|
91
|
+
.finally(release)
|
|
92
|
+
.catch(() => undefined);
|
|
91
93
|
}
|
|
92
94
|
else {
|
|
93
95
|
release();
|
|
94
|
-
void stream.removeSubscription(subscriptionParams);
|
|
96
|
+
void Promise.resolve(stream.removeSubscription(subscriptionParams)).catch(() => undefined);
|
|
95
97
|
}
|
|
96
98
|
}));
|
|
97
99
|
});
|