@instadapp/interop-x 0.0.0-dev.051cd4e
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/.env.example +2 -0
- package/.github/workflows/publish-dev.yml +30 -0
- package/README.md +21 -0
- package/bin/interop-x +2 -0
- package/dist/package.json +72 -0
- package/dist/src/abi/erc20.json +350 -0
- package/dist/src/abi/gnosisSafe.json +747 -0
- package/dist/src/abi/index.js +15 -0
- package/dist/src/abi/interopBridgeToken.json +286 -0
- package/dist/src/abi/interopXGateway.json +184 -0
- package/dist/src/api/index.js +33 -0
- package/dist/src/config/index.js +22 -0
- package/dist/src/constants/addresses.js +20 -0
- package/dist/src/constants/index.js +19 -0
- package/dist/src/constants/itokens.js +13 -0
- package/dist/src/constants/tokens.js +107 -0
- package/dist/src/db/index.js +17 -0
- package/dist/src/db/models/index.js +17 -0
- package/dist/src/db/models/transaction.js +54 -0
- package/dist/src/db/sequelize.js +23 -0
- package/dist/src/index.js +103 -0
- package/dist/src/logger/index.js +138 -0
- package/dist/src/net/index.js +19 -0
- package/dist/src/net/peer/index.js +108 -0
- package/dist/src/net/pool/index.js +125 -0
- package/dist/src/net/protocol/dial/BaseDialProtocol.js +106 -0
- package/dist/src/net/protocol/dial/SignatureDialProtocol.js +56 -0
- package/dist/src/net/protocol/index.js +121 -0
- package/dist/src/tasks/AutoUpdateTask.js +45 -0
- package/dist/src/tasks/BaseTask.js +61 -0
- package/dist/src/tasks/InteropBridge/ProcessWithdrawEvents.js +147 -0
- package/dist/src/tasks/InteropBridge/SyncWithdrawEvents.js +70 -0
- package/dist/src/tasks/InteropXGateway/ProcessDepositEvents.js +150 -0
- package/dist/src/tasks/InteropXGateway/SyncDepositEvents.js +75 -0
- package/dist/src/tasks/index.js +42 -0
- package/dist/src/typechain/Erc20.js +2 -0
- package/dist/src/typechain/GnosisSafe.js +2 -0
- package/dist/src/typechain/InteropBridgeToken.js +2 -0
- package/dist/src/typechain/InteropXGateway.js +2 -0
- package/dist/src/typechain/common.js +2 -0
- package/dist/src/typechain/factories/Erc20__factory.js +367 -0
- package/dist/src/typechain/factories/GnosisSafe__factory.js +1174 -0
- package/dist/src/typechain/factories/InteropBridgeToken__factory.js +459 -0
- package/dist/src/typechain/factories/InteropXGateway__factory.js +265 -0
- package/dist/src/typechain/factories/index.js +14 -0
- package/dist/src/typechain/index.js +35 -0
- package/dist/src/types.js +21 -0
- package/dist/src/utils/index.js +228 -0
- package/package.json +72 -0
- package/patches/@ethersproject+properties+5.6.0.patch +13 -0
- package/src/abi/erc20.json +350 -0
- package/src/abi/gnosisSafe.json +747 -0
- package/src/abi/index.ts +11 -0
- package/src/abi/interopBridgeToken.json +286 -0
- package/src/abi/interopXGateway.json +184 -0
- package/src/api/index.ts +33 -0
- package/src/config/index.ts +32 -0
- package/src/constants/addresses.ts +17 -0
- package/src/constants/index.ts +3 -0
- package/src/constants/itokens.ts +10 -0
- package/src/constants/tokens.ts +104 -0
- package/src/db/index.ts +1 -0
- package/src/db/models/index.ts +1 -0
- package/src/db/models/transaction.ts +96 -0
- package/src/db/sequelize.ts +22 -0
- package/src/index.ts +123 -0
- package/src/logger/index.ts +157 -0
- package/src/net/index.ts +3 -0
- package/src/net/peer/index.ts +120 -0
- package/src/net/pool/index.ts +154 -0
- package/src/net/protocol/dial/BaseDialProtocol.ts +104 -0
- package/src/net/protocol/dial/SignatureDialProtocol.ts +71 -0
- package/src/net/protocol/index.ts +182 -0
- package/src/tasks/AutoUpdateTask.ts +54 -0
- package/src/tasks/BaseTask.ts +75 -0
- package/src/tasks/InteropBridge/ProcessWithdrawEvents.ts +233 -0
- package/src/tasks/InteropBridge/SyncWithdrawEvents.ts +121 -0
- package/src/tasks/InteropXGateway/ProcessDepositEvents.ts +245 -0
- package/src/tasks/InteropXGateway/SyncDepositEvents.ts +126 -0
- package/src/tasks/index.ts +41 -0
- package/src/typechain/Erc20.ts +491 -0
- package/src/typechain/GnosisSafe.ts +1728 -0
- package/src/typechain/InteropBridgeToken.ts +686 -0
- package/src/typechain/InteropXGateway.ts +407 -0
- package/src/typechain/common.ts +44 -0
- package/src/typechain/factories/Erc20__factory.ts +368 -0
- package/src/typechain/factories/GnosisSafe__factory.ts +1178 -0
- package/src/typechain/factories/InteropBridgeToken__factory.ts +466 -0
- package/src/typechain/factories/InteropXGateway__factory.ts +272 -0
- package/src/typechain/factories/index.ts +7 -0
- package/src/typechain/index.ts +12 -0
- package/src/types.ts +39 -0
- package/src/utils/index.ts +307 -0
- package/tsconfig.json +30 -0
@@ -0,0 +1,104 @@
|
|
1
|
+
import pipe from 'it-pipe';
|
2
|
+
import Libp2p from 'libp2p';
|
3
|
+
import PeerId from 'peer-id';
|
4
|
+
import { asyncCallWithTimeout } from '@/utils';
|
5
|
+
import wait from 'waait';
|
6
|
+
|
7
|
+
export class BaseDialProtocol<TRequest extends any, TResponse extends any> {
|
8
|
+
protected libp2p: Libp2p;
|
9
|
+
protected protocol: string;
|
10
|
+
protected timeout = 20000;
|
11
|
+
|
12
|
+
constructor(libp2p: Libp2p, protocol: string) {
|
13
|
+
this.libp2p = libp2p
|
14
|
+
this.protocol = protocol
|
15
|
+
|
16
|
+
this.libp2p.handle(this.protocol, this.handle.bind(this))
|
17
|
+
}
|
18
|
+
|
19
|
+
encode(data: TRequest) {
|
20
|
+
return JSON.stringify(data)
|
21
|
+
}
|
22
|
+
|
23
|
+
encodeResponse(data: TResponse): String | Buffer {
|
24
|
+
return JSON.stringify(data)
|
25
|
+
}
|
26
|
+
|
27
|
+
decode(data: Buffer) {
|
28
|
+
return JSON.parse(data.toString())
|
29
|
+
}
|
30
|
+
|
31
|
+
decodeResponse(data: Buffer): any {
|
32
|
+
return JSON.parse(data.toString())
|
33
|
+
}
|
34
|
+
|
35
|
+
async response(data: TRequest): Promise<TResponse> {
|
36
|
+
return data as TResponse;
|
37
|
+
}
|
38
|
+
|
39
|
+
async handle({ connection, stream }) {
|
40
|
+
const instance = this;
|
41
|
+
|
42
|
+
try {
|
43
|
+
await pipe(stream, async function (source) {
|
44
|
+
for await (const message of source) {
|
45
|
+
const response = instance.encodeResponse(
|
46
|
+
await instance.response(
|
47
|
+
instance.decode(message)
|
48
|
+
)
|
49
|
+
)
|
50
|
+
|
51
|
+
await pipe(
|
52
|
+
[response],
|
53
|
+
stream
|
54
|
+
);
|
55
|
+
}
|
56
|
+
});
|
57
|
+
} catch (err) {
|
58
|
+
console.error(err);
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
async send(data: TRequest, peerId: string) {
|
63
|
+
return await asyncCallWithTimeout<TResponse>(new Promise(async (resolve, reject) => {
|
64
|
+
try {
|
65
|
+
let connection = this.libp2p.connectionManager.get(PeerId.createFromB58String(peerId))
|
66
|
+
|
67
|
+
if (!connection) {
|
68
|
+
|
69
|
+
await wait(5000)
|
70
|
+
|
71
|
+
connection = this.libp2p.connectionManager.get(PeerId.createFromB58String(peerId))
|
72
|
+
|
73
|
+
|
74
|
+
if (!connection) {
|
75
|
+
|
76
|
+
await wait(3000)
|
77
|
+
|
78
|
+
connection = this.libp2p.connectionManager.get(PeerId.createFromB58String(peerId))
|
79
|
+
|
80
|
+
if (!connection) {
|
81
|
+
throw new Error('No connection available')
|
82
|
+
}
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
const { stream } = await connection.newStream([this.protocol])
|
89
|
+
|
90
|
+
const instance = this;
|
91
|
+
|
92
|
+
pipe([this.encode(data)], stream, async function (source) {
|
93
|
+
for await (const message of source) {
|
94
|
+
resolve(instance.decodeResponse(message))
|
95
|
+
stream.close()
|
96
|
+
}
|
97
|
+
});
|
98
|
+
} catch (error) {
|
99
|
+
reject(error)
|
100
|
+
}
|
101
|
+
}), this.timeout)
|
102
|
+
|
103
|
+
}
|
104
|
+
}
|
@@ -0,0 +1,71 @@
|
|
1
|
+
import { BaseDialProtocol } from "./BaseDialProtocol";
|
2
|
+
import wait from "waait";
|
3
|
+
import config from "@/config";
|
4
|
+
import { Transaction } from "@/db";
|
5
|
+
import { buildDataForTransaction, signGnosisSafeTx } from "@/utils";
|
6
|
+
import { addresses } from "@/constants";
|
7
|
+
import { ChainId } from "@/types";
|
8
|
+
|
9
|
+
export interface ISignatureRequest {
|
10
|
+
type: 'source' | 'target' ,
|
11
|
+
transactionHash: string
|
12
|
+
safeTxGas: string
|
13
|
+
safeNonce: string
|
14
|
+
}
|
15
|
+
export interface ISignatureResponse {
|
16
|
+
signer: string,
|
17
|
+
data?: string | null,
|
18
|
+
error?: string | null,
|
19
|
+
}
|
20
|
+
export class SignatureDialProtocol extends BaseDialProtocol<ISignatureRequest, ISignatureResponse> {
|
21
|
+
protected timeout = 30000;
|
22
|
+
|
23
|
+
constructor(libp2p) {
|
24
|
+
super(libp2p, '/interop-x/signatures')
|
25
|
+
}
|
26
|
+
|
27
|
+
async response(data: ISignatureRequest): Promise<ISignatureResponse> {
|
28
|
+
const signer = config.wallet;
|
29
|
+
|
30
|
+
let transaction: Transaction | null;
|
31
|
+
let maxTimeout = 20000;
|
32
|
+
|
33
|
+
do {
|
34
|
+
transaction = await Transaction.findOne({ where: { transactionHash: data.transactionHash } })
|
35
|
+
|
36
|
+
if (!transaction) {
|
37
|
+
await wait(1000);
|
38
|
+
maxTimeout -= 1000;
|
39
|
+
}
|
40
|
+
} while (!transaction && maxTimeout > 0)
|
41
|
+
|
42
|
+
if (!transaction) {
|
43
|
+
return {
|
44
|
+
signer: signer.address,
|
45
|
+
data: null,
|
46
|
+
error: 'Event not found'
|
47
|
+
};
|
48
|
+
}
|
49
|
+
|
50
|
+
console.log("signing:", {
|
51
|
+
to: addresses[transaction.targetChainId].multisend,
|
52
|
+
data: await buildDataForTransaction(transaction, data.type),
|
53
|
+
chainId: transaction.targetChainId as ChainId,
|
54
|
+
safeTxGas: data.safeTxGas,
|
55
|
+
nonce: data.safeNonce,
|
56
|
+
});
|
57
|
+
|
58
|
+
const signedData = await signGnosisSafeTx({
|
59
|
+
to: addresses[transaction.targetChainId].multisend,
|
60
|
+
data: await buildDataForTransaction(transaction, data.type),
|
61
|
+
chainId: transaction.targetChainId as ChainId,
|
62
|
+
safeTxGas: data.safeTxGas,
|
63
|
+
nonce: data.safeNonce,
|
64
|
+
}, { signer });
|
65
|
+
|
66
|
+
return {
|
67
|
+
signer: signer.address,
|
68
|
+
data: signedData
|
69
|
+
}
|
70
|
+
}
|
71
|
+
}
|
@@ -0,0 +1,182 @@
|
|
1
|
+
import { EventEmitter } from "stream";
|
2
|
+
import Libp2p from 'libp2p';
|
3
|
+
import { bufferToInt, rlp } from 'ethereumjs-util'
|
4
|
+
import { SignatureDialProtocol, ISignatureRequest, ISignatureResponse } from "./dial/SignatureDialProtocol";
|
5
|
+
import { IPeerInfo, peerPool } from "..";
|
6
|
+
import config from "@/config";
|
7
|
+
import { Event } from "@/types";
|
8
|
+
import { Transaction } from "@/db";
|
9
|
+
|
10
|
+
export interface ProtocolOptions {
|
11
|
+
/* Handshake timeout in ms (default: 8000) */
|
12
|
+
timeout?: number
|
13
|
+
}
|
14
|
+
|
15
|
+
|
16
|
+
export type Message = {
|
17
|
+
name: string
|
18
|
+
code: number
|
19
|
+
payload?: any
|
20
|
+
response?: number
|
21
|
+
encode: Function
|
22
|
+
decode: Function
|
23
|
+
}
|
24
|
+
|
25
|
+
interface BaseMessageEvent {
|
26
|
+
peerId: string
|
27
|
+
name: string
|
28
|
+
code: number
|
29
|
+
data: any
|
30
|
+
}
|
31
|
+
|
32
|
+
|
33
|
+
interface PeerInfoEvent extends BaseMessageEvent {
|
34
|
+
data: Omit<IPeerInfo, 'id' | 'updated' | 'idle' | 'pooled'>
|
35
|
+
}
|
36
|
+
|
37
|
+
interface TransactionStatusEvent extends BaseMessageEvent {
|
38
|
+
data: Pick<Transaction, 'transactionHash' | 'sourceStatus' | 'sourceTransactionHash' | 'sourceErrors' | 'targetStatus' | 'targetTransactionHash' | 'targetErrors' | 'status'>
|
39
|
+
}
|
40
|
+
|
41
|
+
declare interface Protocol {
|
42
|
+
on(event: 'TransactionStatus', listener: (payload: TransactionStatusEvent) => void): this;
|
43
|
+
on(event: 'PeerInfo', listener: (payload: PeerInfoEvent) => void): this;
|
44
|
+
on(event: string, listener: (payload: BaseMessageEvent) => void): this;
|
45
|
+
}
|
46
|
+
|
47
|
+
class Protocol extends EventEmitter {
|
48
|
+
private libp2p: Libp2p;
|
49
|
+
private topic: string;
|
50
|
+
private protocolMessages: Message[] = [
|
51
|
+
{
|
52
|
+
name: 'PeerInfo',
|
53
|
+
code: 0x01,
|
54
|
+
encode: (info: Pick<IPeerInfo, 'publicAddress'>) => [
|
55
|
+
Buffer.from(info.publicAddress),
|
56
|
+
],
|
57
|
+
decode: ([publicAddress]: [Buffer]) => ({
|
58
|
+
publicAddress: publicAddress.toString(),
|
59
|
+
}),
|
60
|
+
},
|
61
|
+
{
|
62
|
+
name: 'TransactionStatus',
|
63
|
+
code: 0x02,
|
64
|
+
encode: (transaction: Transaction) => [
|
65
|
+
Buffer.from(transaction.transactionHash),
|
66
|
+
|
67
|
+
Buffer.from(transaction.sourceStatus),
|
68
|
+
Buffer.from(transaction.sourceTransactionHash),
|
69
|
+
transaction.sourceErrors ? transaction.sourceErrors.map((e) => Buffer.from(e)) : [],
|
70
|
+
|
71
|
+
Buffer.from(transaction.targetStatus),
|
72
|
+
Buffer.from(transaction.targetTransactionHash),
|
73
|
+
transaction.targetErrors ? transaction.targetErrors.map((e) => Buffer.from(e)) : [],
|
74
|
+
|
75
|
+
Buffer.from(transaction.status),
|
76
|
+
],
|
77
|
+
decode: ([transactionHash, sourceStatus, sourceTransactionHash, sourceErrors, targetStatus, targetTransactionHash, targetErrors, status]: [Buffer, Buffer, Buffer, Buffer[], Buffer, Buffer, Buffer[], Buffer]) => ({
|
78
|
+
transactionHash: transactionHash.toString(),
|
79
|
+
|
80
|
+
sourceStatus: sourceStatus.toString(),
|
81
|
+
sourceTransactionHash: sourceTransactionHash.toString(),
|
82
|
+
sourceErrors: sourceErrors.map((e) => e.toString()),
|
83
|
+
|
84
|
+
targetStatus: targetStatus.toString(),
|
85
|
+
targetTransactionHash: targetTransactionHash.toString(),
|
86
|
+
targetErrors: targetErrors.map((e) => e.toString()),
|
87
|
+
|
88
|
+
status: status.toString(),
|
89
|
+
}),
|
90
|
+
},
|
91
|
+
];
|
92
|
+
private signature: SignatureDialProtocol;
|
93
|
+
|
94
|
+
|
95
|
+
start({ libp2p, topic = null, }) {
|
96
|
+
this.libp2p = libp2p
|
97
|
+
this.topic = topic || 'itnerop-x-protocol'
|
98
|
+
|
99
|
+
if (this.libp2p.isStarted()) this.init()
|
100
|
+
|
101
|
+
this.on('PeerInfo', (payload) => {
|
102
|
+
|
103
|
+
config.events.emit(Event.PEER_CONNECTED, {
|
104
|
+
id: payload.peerId,
|
105
|
+
publicAddress: payload.data.publicAddress,
|
106
|
+
pooled: false,
|
107
|
+
updated: new Date(),
|
108
|
+
})
|
109
|
+
})
|
110
|
+
|
111
|
+
this.signature = new SignatureDialProtocol(this.libp2p);
|
112
|
+
}
|
113
|
+
|
114
|
+
|
115
|
+
init() {
|
116
|
+
this.libp2p.pubsub.subscribe(this.topic)
|
117
|
+
|
118
|
+
this.libp2p.pubsub.on(this.topic, (message) => {
|
119
|
+
try {
|
120
|
+
const [codeBuf, payload]: any = rlp.decode(message.data);
|
121
|
+
|
122
|
+
const code = bufferToInt(codeBuf);
|
123
|
+
|
124
|
+
const protocolMessage = this.protocolMessages.find((m) => m.code === code);
|
125
|
+
if (!protocolMessage) {
|
126
|
+
return;
|
127
|
+
}
|
128
|
+
const decoded = protocolMessage.decode(payload);
|
129
|
+
this.emit(
|
130
|
+
protocolMessage.name,
|
131
|
+
{
|
132
|
+
peerId: message.from,
|
133
|
+
name: protocolMessage.name,
|
134
|
+
code: protocolMessage.code,
|
135
|
+
data: decoded
|
136
|
+
}
|
137
|
+
)
|
138
|
+
|
139
|
+
this.emit('all', {
|
140
|
+
peerId: message.from,
|
141
|
+
name: protocolMessage.name,
|
142
|
+
code: protocolMessage.code,
|
143
|
+
data: decoded,
|
144
|
+
})
|
145
|
+
} catch (err) {
|
146
|
+
console.error(err)
|
147
|
+
}
|
148
|
+
})
|
149
|
+
}
|
150
|
+
|
151
|
+
|
152
|
+
public sendPeerInfo(data: Pick<IPeerInfo, 'publicAddress'>) {
|
153
|
+
const message = this.protocolMessages.find((m) => m.name === 'PeerInfo')!
|
154
|
+
|
155
|
+
const encoded = rlp.encode([message.code, message.encode(data)]);
|
156
|
+
|
157
|
+
this.libp2p.pubsub.publish(this.topic, encoded)
|
158
|
+
}
|
159
|
+
|
160
|
+
public sendTransaction(transaction: Transaction) {
|
161
|
+
const message = this.protocolMessages.find((m) => m.name === 'TransactionStatus')!
|
162
|
+
|
163
|
+
const encoded = rlp.encode([message.code, message.encode(transaction)]);
|
164
|
+
|
165
|
+
this.libp2p.pubsub.publish(this.topic, encoded)
|
166
|
+
}
|
167
|
+
|
168
|
+
async requestSignatures(data: ISignatureRequest, peerIds?: string[]) {
|
169
|
+
try {
|
170
|
+
peerIds = peerIds || peerPool.activePeerIds;
|
171
|
+
const promises = peerIds.map((peerId) => this.signature.send(data, peerId))
|
172
|
+
return (await Promise.allSettled(promises))
|
173
|
+
.map((p) => p.status === 'fulfilled' ? p.value : null)
|
174
|
+
.filter(Boolean) as ISignatureResponse[]
|
175
|
+
} catch (error) {
|
176
|
+
console.log(error);
|
177
|
+
return []
|
178
|
+
}
|
179
|
+
}
|
180
|
+
}
|
181
|
+
|
182
|
+
export const protocol = new Protocol();
|
@@ -0,0 +1,54 @@
|
|
1
|
+
import { BaseTask } from "./BaseTask";
|
2
|
+
import Logger from '@/logger';
|
3
|
+
import packageJson from '../../package.json'
|
4
|
+
import { http } from "@/utils";
|
5
|
+
import { spawn } from 'child_process';
|
6
|
+
import config from "@/config";
|
7
|
+
const currentVersion = packageJson.version;
|
8
|
+
|
9
|
+
class AutoUpdateTask extends BaseTask {
|
10
|
+
pollIntervalMs: number = 60 * 1000
|
11
|
+
|
12
|
+
constructor() {
|
13
|
+
super({
|
14
|
+
logger: new Logger("AutoUpdateTask"),
|
15
|
+
})
|
16
|
+
}
|
17
|
+
|
18
|
+
prePollHandler(): boolean {
|
19
|
+
return config.autoUpdate && !config.isLeadNode();
|
20
|
+
}
|
21
|
+
|
22
|
+
async pollHandler() {
|
23
|
+
|
24
|
+
const { data } = await http.get('https://registry.npmjs.org/@instadapp/interop-x')
|
25
|
+
|
26
|
+
const version = data['dist-tags'].latest
|
27
|
+
|
28
|
+
if (version === currentVersion) {
|
29
|
+
return;
|
30
|
+
}
|
31
|
+
|
32
|
+
this.logger.warn(`New version ${version} available.`)
|
33
|
+
|
34
|
+
|
35
|
+
const update = spawn('npm', ['-g', 'install', '@instadapp/interop-x']);
|
36
|
+
|
37
|
+
update.on("close", () => {
|
38
|
+
this.logger.warn(`Installed version ${version}`)
|
39
|
+
this.logger.warn(`Restarting...`)
|
40
|
+
|
41
|
+
const restart = spawn(process.argv[0], process.argv.slice(1), {
|
42
|
+
cwd: process.cwd(),
|
43
|
+
detached: true,
|
44
|
+
stdio: "inherit"
|
45
|
+
});
|
46
|
+
|
47
|
+
restart.on("close", () => {
|
48
|
+
process.exit()
|
49
|
+
})
|
50
|
+
})
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
export default AutoUpdateTask;
|
@@ -0,0 +1,75 @@
|
|
1
|
+
import config from "@/config";
|
2
|
+
import EventEmitter from "events";
|
3
|
+
import wait from "waait";
|
4
|
+
import Logger from "@/logger";
|
5
|
+
|
6
|
+
export interface IBaseTask {
|
7
|
+
pollCheck(): Promise<void>
|
8
|
+
prePollHandler(): boolean
|
9
|
+
pollHandler(): Promise<void>
|
10
|
+
postPollHandler(): Promise<void>
|
11
|
+
|
12
|
+
start(): Promise<void>
|
13
|
+
stop(): Promise<void>
|
14
|
+
}
|
15
|
+
|
16
|
+
|
17
|
+
export class BaseTask extends EventEmitter implements IBaseTask {
|
18
|
+
logger: Logger
|
19
|
+
started: boolean = false
|
20
|
+
pollIntervalMs: number = 10 * 1000
|
21
|
+
leadNodeOnly: boolean = false
|
22
|
+
|
23
|
+
public constructor({ logger }: { logger?: Logger }) {
|
24
|
+
super()
|
25
|
+
|
26
|
+
this.logger = logger ?? new Logger('BaseTask')
|
27
|
+
}
|
28
|
+
|
29
|
+
async pollCheck() {
|
30
|
+
while (true) {
|
31
|
+
if (!this.started) {
|
32
|
+
return
|
33
|
+
}
|
34
|
+
try {
|
35
|
+
const shouldPoll = this.prePollHandler()
|
36
|
+
if (shouldPoll) {
|
37
|
+
await this.pollHandler()
|
38
|
+
}
|
39
|
+
} catch (err) {
|
40
|
+
this.logger.error(`poll check error:\n${err.message}\ntrace: ${err.stack}`)
|
41
|
+
}
|
42
|
+
|
43
|
+
await this.postPollHandler()
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
prePollHandler(): boolean {
|
48
|
+
if (!this.leadNodeOnly) {
|
49
|
+
return true
|
50
|
+
}
|
51
|
+
|
52
|
+
return config.isLeadNode()
|
53
|
+
}
|
54
|
+
|
55
|
+
async pollHandler() {
|
56
|
+
this.logger.warn('pollHandler not implemented')
|
57
|
+
}
|
58
|
+
|
59
|
+
async postPollHandler() {
|
60
|
+
await wait(this.pollIntervalMs)
|
61
|
+
}
|
62
|
+
|
63
|
+
async start() {
|
64
|
+
this.started = true
|
65
|
+
try {
|
66
|
+
await this.pollCheck()
|
67
|
+
} catch (err) {
|
68
|
+
this.logger.error(`base task error: ${err.message}\ntrace: ${err.stack}`)
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
async stop() {
|
73
|
+
this.started = false
|
74
|
+
}
|
75
|
+
}
|