@drift-labs/sdk 2.48.0-beta.20 → 2.48.0-beta.22
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/VERSION +1 -1
- package/lib/events/eventSubscriber.js +23 -2
- package/lib/events/pollingLogProvider.d.ts +1 -1
- package/lib/events/pollingLogProvider.js +1 -1
- package/lib/events/types.d.ts +9 -3
- package/lib/events/webSocketLogProvider.d.ts +8 -2
- package/lib/events/webSocketLogProvider.js +32 -14
- package/package.json +1 -1
- package/src/events/eventSubscriber.ts +45 -2
- package/src/events/pollingLogProvider.ts +2 -2
- package/src/events/types.ts +11 -3
- package/src/events/webSocketLogProvider.ts +46 -23
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.48.0-beta.
|
|
1
|
+
2.48.0-beta.22
|
|
@@ -27,7 +27,7 @@ class EventSubscriber {
|
|
|
27
27
|
}
|
|
28
28
|
this.eventEmitter = new events_1.EventEmitter();
|
|
29
29
|
if (this.options.logProviderConfig.type === 'websocket') {
|
|
30
|
-
this.logProvider = new webSocketLogProvider_1.WebSocketLogProvider(this.connection, this.address, this.options.commitment, this.options.resubTimeoutMs);
|
|
30
|
+
this.logProvider = new webSocketLogProvider_1.WebSocketLogProvider(this.connection, this.address, this.options.commitment, this.options.logProviderConfig.resubTimeoutMs);
|
|
31
31
|
}
|
|
32
32
|
else {
|
|
33
33
|
this.logProvider = new pollingLogProvider_1.PollingLogProvider(this.connection, this.address, options.commitment, this.options.logProviderConfig.frequency, this.options.logProviderConfig.batchSize);
|
|
@@ -38,6 +38,27 @@ class EventSubscriber {
|
|
|
38
38
|
if (this.logProvider.isSubscribed()) {
|
|
39
39
|
return true;
|
|
40
40
|
}
|
|
41
|
+
if (this.options.logProviderConfig.type === 'websocket') {
|
|
42
|
+
if (this.options.logProviderConfig.resubTimeoutMs) {
|
|
43
|
+
if (this.options.logProviderConfig.maxReconnectAttempts &&
|
|
44
|
+
this.options.logProviderConfig.maxReconnectAttempts > 0) {
|
|
45
|
+
const logProviderConfig = this.options
|
|
46
|
+
.logProviderConfig;
|
|
47
|
+
this.logProvider.eventEmitter.on('reconnect', (reconnectAttempts) => {
|
|
48
|
+
if (reconnectAttempts > logProviderConfig.maxReconnectAttempts) {
|
|
49
|
+
console.log('Failing over to polling');
|
|
50
|
+
this.logProvider.eventEmitter.removeAllListeners('reconnect');
|
|
51
|
+
this.unsubscribe().then(() => {
|
|
52
|
+
this.logProvider = new pollingLogProvider_1.PollingLogProvider(this.connection, this.address, this.options.commitment, logProviderConfig.fallbackFrequency, logProviderConfig.fallbackBatchSize);
|
|
53
|
+
this.logProvider.subscribe((txSig, slot, logs, mostRecentBlockTime) => {
|
|
54
|
+
this.handleTxLogs(txSig, slot, logs, mostRecentBlockTime);
|
|
55
|
+
}, true);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
41
62
|
this.logProvider.subscribe((txSig, slot, logs, mostRecentBlockTime) => {
|
|
42
63
|
this.handleTxLogs(txSig, slot, logs, mostRecentBlockTime);
|
|
43
64
|
}, true);
|
|
@@ -95,7 +116,7 @@ class EventSubscriber {
|
|
|
95
116
|
}
|
|
96
117
|
}
|
|
97
118
|
async unsubscribe() {
|
|
98
|
-
return await this.logProvider.unsubscribe();
|
|
119
|
+
return await this.logProvider.unsubscribe(true);
|
|
99
120
|
}
|
|
100
121
|
parseEventsFromLogs(txSig, slot, logs) {
|
|
101
122
|
const records = [];
|
|
@@ -11,7 +11,7 @@ export declare class PollingLogProvider implements LogProvider {
|
|
|
11
11
|
private mutex;
|
|
12
12
|
private firstFetch;
|
|
13
13
|
constructor(connection: Connection, address: PublicKey, commitment: Commitment, frequency?: number, batchSize?: number);
|
|
14
|
-
subscribe(callback: logProviderCallback, skipHistory?: boolean): boolean
|
|
14
|
+
subscribe(callback: logProviderCallback, skipHistory?: boolean): Promise<boolean>;
|
|
15
15
|
isSubscribed(): boolean;
|
|
16
16
|
unsubscribe(): Promise<boolean>;
|
|
17
17
|
}
|
|
@@ -11,7 +11,7 @@ class PollingLogProvider {
|
|
|
11
11
|
this.firstFetch = true;
|
|
12
12
|
this.finality = commitment === 'finalized' ? 'finalized' : 'confirmed';
|
|
13
13
|
}
|
|
14
|
-
subscribe(callback, skipHistory) {
|
|
14
|
+
async subscribe(callback, skipHistory) {
|
|
15
15
|
if (this.intervalId) {
|
|
16
16
|
return true;
|
|
17
17
|
}
|
package/lib/events/types.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import { Commitment, PublicKey, TransactionSignature } from '@solana/web3.js';
|
|
2
3
|
import { DepositRecord, FundingPaymentRecord, FundingRateRecord, LiquidationRecord, NewUserRecord, OrderActionRecord, OrderRecord, SettlePnlRecord, LPRecord, InsuranceFundRecord, SpotInterestRecord, InsuranceFundStakeRecord, CurveRecord, SwapRecord } from '../index';
|
|
4
|
+
import { EventEmitter } from 'events';
|
|
3
5
|
export type EventSubscriptionOptions = {
|
|
4
6
|
address?: PublicKey;
|
|
5
7
|
eventTypes?: EventType[];
|
|
@@ -10,7 +12,6 @@ export type EventSubscriptionOptions = {
|
|
|
10
12
|
maxTx?: number;
|
|
11
13
|
logProviderConfig?: LogProviderConfig;
|
|
12
14
|
untilTx?: TransactionSignature;
|
|
13
|
-
resubTimeoutMs?: number;
|
|
14
15
|
};
|
|
15
16
|
export declare const DefaultEventSubscriptionOptions: EventSubscriptionOptions;
|
|
16
17
|
export type EventSubscriptionOrderBy = 'blockchain' | 'client';
|
|
@@ -49,11 +50,16 @@ export type SortFn = (currentRecord: EventMap[EventType], newRecord: EventMap[Ev
|
|
|
49
50
|
export type logProviderCallback = (txSig: TransactionSignature, slot: number, logs: string[], mostRecentBlockTime: number | undefined) => void;
|
|
50
51
|
export interface LogProvider {
|
|
51
52
|
isSubscribed(): boolean;
|
|
52
|
-
subscribe(callback: logProviderCallback, skipHistory?: boolean): boolean
|
|
53
|
-
unsubscribe(): Promise<boolean>;
|
|
53
|
+
subscribe(callback: logProviderCallback, skipHistory?: boolean): Promise<boolean>;
|
|
54
|
+
unsubscribe(external?: boolean): Promise<boolean>;
|
|
55
|
+
eventEmitter?: EventEmitter;
|
|
54
56
|
}
|
|
55
57
|
export type WebSocketLogProviderConfig = {
|
|
56
58
|
type: 'websocket';
|
|
59
|
+
resubTimeoutMs?: number;
|
|
60
|
+
maxReconnectAttempts?: number;
|
|
61
|
+
fallbackFrequency?: number;
|
|
62
|
+
fallbackBatchSize?: number;
|
|
57
63
|
};
|
|
58
64
|
export type PollingLogProviderConfig = {
|
|
59
65
|
type: 'polling';
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import { LogProvider, logProviderCallback } from './types';
|
|
2
3
|
import { Commitment, Connection, PublicKey } from '@solana/web3.js';
|
|
4
|
+
import { EventEmitter } from 'events';
|
|
3
5
|
export declare class WebSocketLogProvider implements LogProvider {
|
|
4
6
|
private connection;
|
|
5
7
|
private address;
|
|
@@ -7,12 +9,16 @@ export declare class WebSocketLogProvider implements LogProvider {
|
|
|
7
9
|
private resubTimeoutMs?;
|
|
8
10
|
private subscriptionId;
|
|
9
11
|
private isUnsubscribing;
|
|
12
|
+
private externalUnsubscribe;
|
|
10
13
|
private receivingData;
|
|
11
14
|
private timeoutId?;
|
|
15
|
+
private reconnectAttempts;
|
|
16
|
+
eventEmitter?: EventEmitter;
|
|
12
17
|
private callback?;
|
|
13
18
|
constructor(connection: Connection, address: PublicKey, commitment: Commitment, resubTimeoutMs?: number);
|
|
14
|
-
subscribe(callback: logProviderCallback): boolean
|
|
19
|
+
subscribe(callback: logProviderCallback): Promise<boolean>;
|
|
20
|
+
setSubscription(callback: logProviderCallback): void;
|
|
15
21
|
isSubscribed(): boolean;
|
|
16
|
-
unsubscribe(): Promise<boolean>;
|
|
22
|
+
unsubscribe(external?: boolean): Promise<boolean>;
|
|
17
23
|
private setTimeout;
|
|
18
24
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.WebSocketLogProvider = void 0;
|
|
4
|
+
const events_1 = require("events");
|
|
4
5
|
class WebSocketLogProvider {
|
|
5
6
|
constructor(connection, address, commitment, resubTimeoutMs) {
|
|
6
7
|
this.connection = connection;
|
|
@@ -8,13 +9,31 @@ class WebSocketLogProvider {
|
|
|
8
9
|
this.commitment = commitment;
|
|
9
10
|
this.resubTimeoutMs = resubTimeoutMs;
|
|
10
11
|
this.isUnsubscribing = false;
|
|
12
|
+
this.externalUnsubscribe = false;
|
|
11
13
|
this.receivingData = false;
|
|
14
|
+
this.reconnectAttempts = 0;
|
|
15
|
+
if (this.resubTimeoutMs) {
|
|
16
|
+
this.eventEmitter = new events_1.EventEmitter();
|
|
17
|
+
}
|
|
12
18
|
}
|
|
13
|
-
subscribe(callback) {
|
|
19
|
+
async subscribe(callback) {
|
|
14
20
|
if (this.subscriptionId) {
|
|
15
21
|
return true;
|
|
16
22
|
}
|
|
17
23
|
this.callback = callback;
|
|
24
|
+
try {
|
|
25
|
+
this.setSubscription(callback);
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
// Sometimes ws connection isn't ready, give it a few secs
|
|
29
|
+
setTimeout(() => this.setSubscription(callback), 2000);
|
|
30
|
+
}
|
|
31
|
+
if (this.resubTimeoutMs) {
|
|
32
|
+
this.setTimeout();
|
|
33
|
+
}
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
setSubscription(callback) {
|
|
18
37
|
this.subscriptionId = this.connection.onLogs(this.address, (logs, ctx) => {
|
|
19
38
|
if (this.resubTimeoutMs && !this.isUnsubscribing) {
|
|
20
39
|
this.receivingData = true;
|
|
@@ -23,30 +42,27 @@ class WebSocketLogProvider {
|
|
|
23
42
|
}
|
|
24
43
|
callback(logs.signature, ctx.slot, logs.logs, undefined);
|
|
25
44
|
}, this.commitment);
|
|
26
|
-
if (this.resubTimeoutMs) {
|
|
27
|
-
this.setTimeout();
|
|
28
|
-
}
|
|
29
|
-
return true;
|
|
30
45
|
}
|
|
31
46
|
isSubscribed() {
|
|
32
47
|
return this.subscriptionId !== undefined;
|
|
33
48
|
}
|
|
34
|
-
async unsubscribe() {
|
|
49
|
+
async unsubscribe(external = false) {
|
|
35
50
|
this.isUnsubscribing = true;
|
|
51
|
+
this.externalUnsubscribe = external;
|
|
36
52
|
clearTimeout(this.timeoutId);
|
|
53
|
+
this.timeoutId = undefined;
|
|
37
54
|
if (this.subscriptionId !== undefined) {
|
|
38
|
-
|
|
39
|
-
.removeOnLogsListener(this.subscriptionId)
|
|
40
|
-
.then(() => {
|
|
55
|
+
try {
|
|
56
|
+
await this.connection.removeOnLogsListener(this.subscriptionId);
|
|
41
57
|
this.subscriptionId = undefined;
|
|
42
58
|
this.isUnsubscribing = false;
|
|
43
59
|
return true;
|
|
44
|
-
}
|
|
45
|
-
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
46
62
|
console.log('Error unsubscribing from logs: ', err);
|
|
47
63
|
this.isUnsubscribing = false;
|
|
48
64
|
return false;
|
|
49
|
-
}
|
|
65
|
+
}
|
|
50
66
|
}
|
|
51
67
|
else {
|
|
52
68
|
this.isUnsubscribing = false;
|
|
@@ -55,14 +71,16 @@ class WebSocketLogProvider {
|
|
|
55
71
|
}
|
|
56
72
|
setTimeout() {
|
|
57
73
|
this.timeoutId = setTimeout(async () => {
|
|
58
|
-
if (this.isUnsubscribing) {
|
|
74
|
+
if (this.isUnsubscribing || this.externalUnsubscribe) {
|
|
59
75
|
// If we are in the process of unsubscribing, do not attempt to resubscribe
|
|
60
76
|
return;
|
|
61
77
|
}
|
|
62
78
|
if (this.receivingData) {
|
|
63
|
-
console.log(`No log data in ${this.resubTimeoutMs}ms, resubscribing`);
|
|
79
|
+
console.log(`No log data in ${this.resubTimeoutMs}ms, resubscribing on attempt ${this.reconnectAttempts + 1}`);
|
|
64
80
|
await this.unsubscribe();
|
|
65
81
|
this.receivingData = false;
|
|
82
|
+
this.reconnectAttempts++;
|
|
83
|
+
this.eventEmitter.emit('reconnect', this.reconnectAttempts);
|
|
66
84
|
this.subscribe(this.callback);
|
|
67
85
|
}
|
|
68
86
|
}, this.resubTimeoutMs);
|
package/package.json
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
EventMap,
|
|
9
9
|
LogProvider,
|
|
10
10
|
EventSubscriberEvents,
|
|
11
|
+
WebSocketLogProviderConfig,
|
|
11
12
|
} from './types';
|
|
12
13
|
import { TxEventCache } from './txEventCache';
|
|
13
14
|
import { EventList } from './eventList';
|
|
@@ -57,7 +58,7 @@ export class EventSubscriber {
|
|
|
57
58
|
this.connection,
|
|
58
59
|
this.address,
|
|
59
60
|
this.options.commitment,
|
|
60
|
-
this.options.resubTimeoutMs
|
|
61
|
+
this.options.logProviderConfig.resubTimeoutMs
|
|
61
62
|
);
|
|
62
63
|
} else {
|
|
63
64
|
this.logProvider = new PollingLogProvider(
|
|
@@ -76,6 +77,48 @@ export class EventSubscriber {
|
|
|
76
77
|
return true;
|
|
77
78
|
}
|
|
78
79
|
|
|
80
|
+
if (this.options.logProviderConfig.type === 'websocket') {
|
|
81
|
+
if (this.options.logProviderConfig.resubTimeoutMs) {
|
|
82
|
+
if (
|
|
83
|
+
this.options.logProviderConfig.maxReconnectAttempts &&
|
|
84
|
+
this.options.logProviderConfig.maxReconnectAttempts > 0
|
|
85
|
+
) {
|
|
86
|
+
const logProviderConfig = this.options
|
|
87
|
+
.logProviderConfig as WebSocketLogProviderConfig;
|
|
88
|
+
this.logProvider.eventEmitter.on(
|
|
89
|
+
'reconnect',
|
|
90
|
+
(reconnectAttempts) => {
|
|
91
|
+
if (
|
|
92
|
+
reconnectAttempts > logProviderConfig.maxReconnectAttempts
|
|
93
|
+
) {
|
|
94
|
+
console.log('Failing over to polling');
|
|
95
|
+
this.logProvider.eventEmitter.removeAllListeners('reconnect');
|
|
96
|
+
this.unsubscribe().then(() => {
|
|
97
|
+
this.logProvider = new PollingLogProvider(
|
|
98
|
+
this.connection,
|
|
99
|
+
this.address,
|
|
100
|
+
this.options.commitment,
|
|
101
|
+
logProviderConfig.fallbackFrequency,
|
|
102
|
+
logProviderConfig.fallbackBatchSize
|
|
103
|
+
);
|
|
104
|
+
this.logProvider.subscribe(
|
|
105
|
+
(txSig, slot, logs, mostRecentBlockTime) => {
|
|
106
|
+
this.handleTxLogs(
|
|
107
|
+
txSig,
|
|
108
|
+
slot,
|
|
109
|
+
logs,
|
|
110
|
+
mostRecentBlockTime
|
|
111
|
+
);
|
|
112
|
+
},
|
|
113
|
+
true
|
|
114
|
+
);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
79
122
|
this.logProvider.subscribe((txSig, slot, logs, mostRecentBlockTime) => {
|
|
80
123
|
this.handleTxLogs(txSig, slot, logs, mostRecentBlockTime);
|
|
81
124
|
}, true);
|
|
@@ -159,7 +202,7 @@ export class EventSubscriber {
|
|
|
159
202
|
}
|
|
160
203
|
|
|
161
204
|
public async unsubscribe(): Promise<boolean> {
|
|
162
|
-
return await this.logProvider.unsubscribe();
|
|
205
|
+
return await this.logProvider.unsubscribe(true);
|
|
163
206
|
}
|
|
164
207
|
|
|
165
208
|
private parseEventsFromLogs(
|
|
@@ -25,10 +25,10 @@ export class PollingLogProvider implements LogProvider {
|
|
|
25
25
|
this.finality = commitment === 'finalized' ? 'finalized' : 'confirmed';
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
public subscribe(
|
|
28
|
+
public async subscribe(
|
|
29
29
|
callback: logProviderCallback,
|
|
30
30
|
skipHistory?: boolean
|
|
31
|
-
): boolean {
|
|
31
|
+
): Promise<boolean> {
|
|
32
32
|
if (this.intervalId) {
|
|
33
33
|
return true;
|
|
34
34
|
}
|
package/src/events/types.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
CurveRecord,
|
|
16
16
|
SwapRecord,
|
|
17
17
|
} from '../index';
|
|
18
|
+
import { EventEmitter } from 'events';
|
|
18
19
|
|
|
19
20
|
export type EventSubscriptionOptions = {
|
|
20
21
|
address?: PublicKey;
|
|
@@ -28,7 +29,6 @@ export type EventSubscriptionOptions = {
|
|
|
28
29
|
// when the subscription starts, client might want to backtrack and fetch old tx's
|
|
29
30
|
// this specifies how far to backtrack
|
|
30
31
|
untilTx?: TransactionSignature;
|
|
31
|
-
resubTimeoutMs?: number;
|
|
32
32
|
};
|
|
33
33
|
|
|
34
34
|
export const DefaultEventSubscriptionOptions: EventSubscriptionOptions = {
|
|
@@ -127,12 +127,20 @@ export type logProviderCallback = (
|
|
|
127
127
|
|
|
128
128
|
export interface LogProvider {
|
|
129
129
|
isSubscribed(): boolean;
|
|
130
|
-
subscribe(
|
|
131
|
-
|
|
130
|
+
subscribe(
|
|
131
|
+
callback: logProviderCallback,
|
|
132
|
+
skipHistory?: boolean
|
|
133
|
+
): Promise<boolean>;
|
|
134
|
+
unsubscribe(external?: boolean): Promise<boolean>;
|
|
135
|
+
eventEmitter?: EventEmitter;
|
|
132
136
|
}
|
|
133
137
|
|
|
134
138
|
export type WebSocketLogProviderConfig = {
|
|
135
139
|
type: 'websocket';
|
|
140
|
+
resubTimeoutMs?: number;
|
|
141
|
+
maxReconnectAttempts?: number;
|
|
142
|
+
fallbackFrequency?: number;
|
|
143
|
+
fallbackBatchSize?: number;
|
|
136
144
|
};
|
|
137
145
|
|
|
138
146
|
export type PollingLogProviderConfig = {
|
|
@@ -1,25 +1,48 @@
|
|
|
1
1
|
import { LogProvider, logProviderCallback } from './types';
|
|
2
2
|
import { Commitment, Connection, PublicKey } from '@solana/web3.js';
|
|
3
|
+
import { EventEmitter } from 'events';
|
|
3
4
|
|
|
4
5
|
export class WebSocketLogProvider implements LogProvider {
|
|
5
6
|
private subscriptionId: number;
|
|
6
7
|
private isUnsubscribing = false;
|
|
8
|
+
private externalUnsubscribe = false;
|
|
7
9
|
private receivingData = false;
|
|
8
10
|
private timeoutId?: NodeJS.Timeout;
|
|
11
|
+
private reconnectAttempts = 0;
|
|
12
|
+
eventEmitter?: EventEmitter;
|
|
9
13
|
private callback?: logProviderCallback;
|
|
10
14
|
public constructor(
|
|
11
15
|
private connection: Connection,
|
|
12
16
|
private address: PublicKey,
|
|
13
17
|
private commitment: Commitment,
|
|
14
18
|
private resubTimeoutMs?: number
|
|
15
|
-
) {
|
|
19
|
+
) {
|
|
20
|
+
if (this.resubTimeoutMs) {
|
|
21
|
+
this.eventEmitter = new EventEmitter();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
16
24
|
|
|
17
|
-
public subscribe(callback: logProviderCallback): boolean {
|
|
25
|
+
public async subscribe(callback: logProviderCallback): Promise<boolean> {
|
|
18
26
|
if (this.subscriptionId) {
|
|
19
27
|
return true;
|
|
20
28
|
}
|
|
21
29
|
|
|
22
30
|
this.callback = callback;
|
|
31
|
+
try {
|
|
32
|
+
this.setSubscription(callback);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
// Sometimes ws connection isn't ready, give it a few secs
|
|
35
|
+
setTimeout(() => this.setSubscription(callback), 2000);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (this.resubTimeoutMs) {
|
|
39
|
+
this.setTimeout();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public setSubscription(callback: logProviderCallback): void {
|
|
23
46
|
this.subscriptionId = this.connection.onLogs(
|
|
24
47
|
this.address,
|
|
25
48
|
(logs, ctx) => {
|
|
@@ -32,35 +55,29 @@ export class WebSocketLogProvider implements LogProvider {
|
|
|
32
55
|
},
|
|
33
56
|
this.commitment
|
|
34
57
|
);
|
|
35
|
-
|
|
36
|
-
if (this.resubTimeoutMs) {
|
|
37
|
-
this.setTimeout();
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return true;
|
|
41
58
|
}
|
|
42
59
|
|
|
43
60
|
public isSubscribed(): boolean {
|
|
44
61
|
return this.subscriptionId !== undefined;
|
|
45
62
|
}
|
|
46
63
|
|
|
47
|
-
public async unsubscribe(): Promise<boolean> {
|
|
64
|
+
public async unsubscribe(external = false): Promise<boolean> {
|
|
48
65
|
this.isUnsubscribing = true;
|
|
66
|
+
this.externalUnsubscribe = external;
|
|
49
67
|
clearTimeout(this.timeoutId);
|
|
68
|
+
this.timeoutId = undefined;
|
|
50
69
|
|
|
51
70
|
if (this.subscriptionId !== undefined) {
|
|
52
|
-
|
|
53
|
-
.removeOnLogsListener(this.subscriptionId)
|
|
54
|
-
.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
return false;
|
|
63
|
-
});
|
|
71
|
+
try {
|
|
72
|
+
await this.connection.removeOnLogsListener(this.subscriptionId);
|
|
73
|
+
this.subscriptionId = undefined;
|
|
74
|
+
this.isUnsubscribing = false;
|
|
75
|
+
return true;
|
|
76
|
+
} catch (err) {
|
|
77
|
+
console.log('Error unsubscribing from logs: ', err);
|
|
78
|
+
this.isUnsubscribing = false;
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
64
81
|
} else {
|
|
65
82
|
this.isUnsubscribing = false;
|
|
66
83
|
return true;
|
|
@@ -69,15 +86,21 @@ export class WebSocketLogProvider implements LogProvider {
|
|
|
69
86
|
|
|
70
87
|
private setTimeout(): void {
|
|
71
88
|
this.timeoutId = setTimeout(async () => {
|
|
72
|
-
if (this.isUnsubscribing) {
|
|
89
|
+
if (this.isUnsubscribing || this.externalUnsubscribe) {
|
|
73
90
|
// If we are in the process of unsubscribing, do not attempt to resubscribe
|
|
74
91
|
return;
|
|
75
92
|
}
|
|
76
93
|
|
|
77
94
|
if (this.receivingData) {
|
|
78
|
-
console.log(
|
|
95
|
+
console.log(
|
|
96
|
+
`No log data in ${this.resubTimeoutMs}ms, resubscribing on attempt ${
|
|
97
|
+
this.reconnectAttempts + 1
|
|
98
|
+
}`
|
|
99
|
+
);
|
|
79
100
|
await this.unsubscribe();
|
|
80
101
|
this.receivingData = false;
|
|
102
|
+
this.reconnectAttempts++;
|
|
103
|
+
this.eventEmitter.emit('reconnect', this.reconnectAttempts);
|
|
81
104
|
this.subscribe(this.callback);
|
|
82
105
|
}
|
|
83
106
|
}, this.resubTimeoutMs);
|