Skip to content

Commit 6d74ace

Browse files
committed
feat: batch accounts for less connects grpc drift client subscriber
1 parent a1719bb commit 6d74ace

File tree

3 files changed

+392
-13
lines changed

3 files changed

+392
-13
lines changed

sdk/src/accounts/grpcAccountSubscriber.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,16 @@ export class grpcAccountSubscriber<T> extends WebSocketAccountSubscriber<T> {
3939
program: Program,
4040
accountPublicKey: PublicKey,
4141
decodeBuffer?: (buffer: Buffer) => U,
42-
resubOpts?: ResubOpts
42+
resubOpts?: ResubOpts,
43+
clientProp?: Client
4344
): Promise<grpcAccountSubscriber<U>> {
44-
const client = await createClient(
45-
grpcConfigs.endpoint,
46-
grpcConfigs.token,
47-
grpcConfigs.channelOptions ?? {}
48-
);
45+
const client = clientProp
46+
? clientProp
47+
: await createClient(
48+
grpcConfigs.endpoint,
49+
grpcConfigs.token,
50+
grpcConfigs.channelOptions ?? {}
51+
);
4952
const commitmentLevel =
5053
// @ts-ignore :: isomorphic exported enum fails typescript but will work at runtime
5154
grpcConfigs.commitmentLevel ?? CommitmentLevel.CONFIRMED;

sdk/src/accounts/grpcDriftClientAccountSubscriber.ts

Lines changed: 67 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,15 @@ import {
99
} from '../addresses/pda';
1010
import { DelistedMarketSetting, GrpcConfigs, ResubOpts } from './types';
1111
import { grpcAccountSubscriber } from './grpcAccountSubscriber';
12+
import { grpcMultiAccountSubscriber } from './grpcMultiAccountSubscriber';
1213
import { PerpMarketAccount, SpotMarketAccount, StateAccount } from '../types';
1314
import { getOracleId } from '../oracles/oracleId';
15+
import { Client, createClient } from '../isomorphic/grpc';
1416

1517
export class gprcDriftClientAccountSubscriber extends WebSocketDriftClientAccountSubscriber {
1618
private grpcConfigs: GrpcConfigs;
19+
private perpMarketsSubscriber?: grpcMultiAccountSubscriber<PerpMarketAccount>;
20+
private spotMarketsSubscriber?: grpcMultiAccountSubscriber<SpotMarketAccount>;
1721

1822
constructor(
1923
grpcConfigs: GrpcConfigs,
@@ -94,12 +98,9 @@ export class gprcDriftClientAccountSubscriber extends WebSocketDriftClientAccoun
9498
// set initial data to avoid spamming getAccountInfo calls in webSocketAccountSubscriber
9599
await this.setInitialData();
96100

101+
// subscribe to perp + spot markets using two gRPC streams and subscribe to oracles
97102
await Promise.all([
98-
// subscribe to market accounts
99-
this.subscribeToPerpMarketAccounts(),
100-
// subscribe to spot market accounts
101-
this.subscribeToSpotMarketAccounts(),
102-
// subscribe to oracles
103+
this.subscribeToPerpAndSpotMarkets(),
103104
this.subscribeToOracles(),
104105
]);
105106

@@ -120,8 +121,64 @@ export class gprcDriftClientAccountSubscriber extends WebSocketDriftClientAccoun
120121
return true;
121122
}
122123

124+
private async subscribeToPerpAndSpotMarkets(): Promise<boolean> {
125+
const [perpMarketPubkeys, spotMarketPubkeys] = await Promise.all([
126+
Promise.all(
127+
this.perpMarketIndexes.map((marketIndex) =>
128+
getPerpMarketPublicKey(this.program.programId, marketIndex)
129+
)
130+
),
131+
Promise.all(
132+
this.spotMarketIndexes.map((marketIndex) =>
133+
getSpotMarketPublicKey(this.program.programId, marketIndex)
134+
)
135+
),
136+
]);
137+
138+
this.perpMarketsSubscriber =
139+
await grpcMultiAccountSubscriber.create<PerpMarketAccount>(
140+
this.grpcConfigs,
141+
'PerpMarket',
142+
this.program,
143+
undefined,
144+
this.resubOpts
145+
);
146+
await this.perpMarketsSubscriber.subscribe(
147+
perpMarketPubkeys,
148+
(_accountId, data) => {
149+
this.eventEmitter.emit(
150+
'perpMarketAccountUpdate',
151+
data as PerpMarketAccount
152+
);
153+
this.eventEmitter.emit('update');
154+
}
155+
);
156+
157+
this.spotMarketsSubscriber =
158+
await grpcMultiAccountSubscriber.create<SpotMarketAccount>(
159+
this.grpcConfigs,
160+
'SpotMarket',
161+
this.program,
162+
undefined,
163+
this.resubOpts
164+
);
165+
await this.spotMarketsSubscriber.subscribe(
166+
spotMarketPubkeys,
167+
(_accountId, data) => {
168+
this.eventEmitter.emit(
169+
'spotMarketAccountUpdate',
170+
data as SpotMarketAccount
171+
);
172+
this.eventEmitter.emit('update');
173+
}
174+
);
175+
176+
return true;
177+
}
178+
123179
override async subscribeToSpotMarketAccount(
124-
marketIndex: number
180+
marketIndex: number,
181+
spotMarketClient?: Client
125182
): Promise<boolean> {
126183
const marketPublicKey = await getSpotMarketPublicKey(
127184
this.program.programId,
@@ -147,7 +204,10 @@ export class gprcDriftClientAccountSubscriber extends WebSocketDriftClientAccoun
147204
return true;
148205
}
149206

150-
async subscribeToPerpMarketAccount(marketIndex: number): Promise<boolean> {
207+
async subscribeToPerpMarketAccount(
208+
marketIndex: number,
209+
perpMarketClient?: Client
210+
): Promise<boolean> {
151211
const perpMarketPublicKey = await getPerpMarketPublicKey(
152212
this.program.programId,
153213
marketIndex

0 commit comments

Comments
 (0)