Skip to content

Commit b75b9dc

Browse files
committed
feat(wallet): add optional pollController$ dependency
Used to control polling. Should emit: - `true` to switch on polling - `false` to switch off polling
1 parent 2618bb3 commit b75b9dc

File tree

3 files changed

+56
-7
lines changed

3 files changed

+56
-7
lines changed

packages/wallet/src/Wallets/BaseWallet.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,8 @@ export interface BaseWalletDependencies {
189189
readonly connectionStatusTracker$?: ConnectionStatusTracker;
190190
readonly publicCredentialsManager: PublicCredentialsManager;
191191
readonly inputResolver?: Cardano.InputResolver;
192+
/** control whether tip tracker should be polling */
193+
readonly pollController$?: Observable<boolean>;
192194
}
193195

194196
export interface SubmitTxOptions {
@@ -327,7 +329,8 @@ export class BaseWallet implements ObservableWallet {
327329
publicCredentialsManager,
328330
stores = createInMemoryWalletStores(),
329331
connectionStatusTracker$ = createSimpleConnectionStatusTracker(),
330-
inputResolver
332+
inputResolver,
333+
pollController$ = of(true)
331334
}: BaseWalletDependencies
332335
) {
333336
this.#logger = contextLogger(logger, name);
@@ -397,6 +400,7 @@ export class BaseWallet implements ObservableWallet {
397400
logger: contextLogger(this.#logger, 'tip$'),
398401
maxPollInterval: maxInterval,
399402
minPollInterval: pollInterval,
403+
pollController$,
400404
provider$: pollProvider({
401405
cancel$,
402406
logger: contextLogger(this.#logger, 'tip$'),

packages/wallet/src/services/TipTracker.ts

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ export interface TipTrackerProps {
2727
provider$: Observable<Cardano.Tip>;
2828
syncStatus: SyncStatus;
2929
connectionStatus$: Observable<ConnectionStatus>;
30+
/** control whether tip tracker should be polling */
31+
pollController$: Observable<boolean>;
3032
store: DocumentStore<Cardano.Tip>;
3133
/** Once */
3234
minPollInterval: Milliseconds;
@@ -46,7 +48,16 @@ export class TipTracker extends PersistentDocumentTrackerSubject<Cardano.Tip> {
4648
#logger: Logger;
4749

4850
constructor(
49-
{ provider$, minPollInterval, maxPollInterval, store, syncStatus, connectionStatus$, logger }: TipTrackerProps,
51+
{
52+
provider$,
53+
pollController$,
54+
minPollInterval,
55+
maxPollInterval,
56+
store,
57+
syncStatus,
58+
connectionStatus$,
59+
logger
60+
}: TipTrackerProps,
5061
{ externalTrigger$ = new Subject() }: TipTrackerInternals = {}
5162
) {
5263
super(
@@ -63,14 +74,17 @@ export class TipTracker extends PersistentDocumentTrackerSubject<Cardano.Tip> {
6374
// trigger fetch on start
6475
startWith(null)
6576
),
66-
connectionStatus$
77+
connectionStatus$,
78+
pollController$
6779
]).pipe(
68-
tap(([, connectionStatus]) => {
69-
logger.debug(connectionStatus === ConnectionStatus.down ? 'Skipping fetch tip' : 'Fetching tip...');
80+
tap(([, connectionStatus, poll]) => {
81+
logger.debug(
82+
connectionStatus === ConnectionStatus.down || !poll ? 'Skipping fetch tip' : 'Fetching tip...'
83+
);
7084
}),
7185
// Throttle syncing by interval, cancel ongoing request on external trigger
72-
exhaustMap(([, connectionStatus]) =>
73-
connectionStatus === ConnectionStatus.down
86+
exhaustMap(([, connectionStatus, poll]) =>
87+
connectionStatus === ConnectionStatus.down || !poll
7488
? EMPTY
7589
: provider$.pipe(takeUntil(externalTrigger$.pipe(tap(() => logger.debug('Tip fetch canceled')))))
7690
),

packages/wallet/test/services/TipTracker.test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ describe('TipTracker', () => {
3636
logger,
3737
maxPollInterval: Number.MAX_VALUE,
3838
minPollInterval: pollInterval,
39+
pollController$: of(true),
3940
provider$,
4041
store,
4142
syncStatus: { isSettled$: NEVER } as unknown as SyncStatus
@@ -62,6 +63,7 @@ describe('TipTracker', () => {
6263
logger,
6364
maxPollInterval: Number.MAX_VALUE,
6465
minPollInterval: poll,
66+
pollController$: of(true),
6567
provider$,
6668
store,
6769
syncStatus: syncStatus as SyncStatus
@@ -84,6 +86,7 @@ describe('TipTracker', () => {
8486
logger,
8587
maxPollInterval: Number.MAX_VALUE,
8688
minPollInterval: pollInterval,
89+
pollController$: of(true),
8790
provider$,
8891
store,
8992
syncStatus: syncStatus as SyncStatus
@@ -105,6 +108,7 @@ describe('TipTracker', () => {
105108
logger,
106109
maxPollInterval: Number.MAX_VALUE,
107110
minPollInterval: pollInterval,
111+
pollController$: of(true),
108112
provider$,
109113
store,
110114
syncStatus: syncStatus as SyncStatus
@@ -131,6 +135,7 @@ describe('TipTracker', () => {
131135
logger,
132136
maxPollInterval: Number.MAX_VALUE,
133137
minPollInterval: pollInterval,
138+
pollController$: of(true),
134139
provider$,
135140
store,
136141
syncStatus: syncStatus as SyncStatus
@@ -154,6 +159,7 @@ describe('TipTracker', () => {
154159
logger,
155160
maxPollInterval: 6,
156161
minPollInterval: pollInterval,
162+
pollController$: of(true),
157163
provider$,
158164
store,
159165
syncStatus: syncStatus as SyncStatus
@@ -177,6 +183,7 @@ describe('TipTracker', () => {
177183
logger,
178184
maxPollInterval: Number.MAX_VALUE,
179185
minPollInterval: 0,
186+
pollController$: of(true),
180187
provider$,
181188
store,
182189
syncStatus: syncStatus as SyncStatus
@@ -185,6 +192,29 @@ describe('TipTracker', () => {
185192
});
186193
});
187194

195+
it('is not polling while last poll$ emission is false', () => {
196+
createTestScheduler().run(({ cold, hot, expectObservable }) => {
197+
const poll$ = hot('t----f----t|', trueFalse);
198+
const syncStatus: Partial<SyncStatus> = { isSettled$: cold('tftft', trueFalse) };
199+
const provider$ = createStubObservable<Cardano.Tip>(
200+
cold('a|', mockTips),
201+
cold('b|', mockTips),
202+
cold('c|', mockTips)
203+
);
204+
const tracker$ = new TipTracker({
205+
connectionStatus$,
206+
logger,
207+
maxPollInterval: Number.MAX_VALUE,
208+
minPollInterval: pollInterval,
209+
pollController$: poll$,
210+
provider$,
211+
store,
212+
syncStatus: syncStatus as SyncStatus
213+
});
214+
expectObservable(tracker$, '^-----------!').toBe('a--b------c', mockTips);
215+
});
216+
});
217+
188218
it('syncStatus timeout while connection is down does not emit tip updates', () => {
189219
createTestScheduler().run(({ cold, hot, expectObservable, expectSubscriptions }) => {
190220
const syncStatus: Partial<SyncStatus> = { isSettled$: hot('10ms |') };
@@ -195,6 +225,7 @@ describe('TipTracker', () => {
195225
logger,
196226
maxPollInterval: 6,
197227
minPollInterval: 0,
228+
pollController$: of(true),
198229
provider$,
199230
store,
200231
syncStatus: syncStatus as SyncStatus

0 commit comments

Comments
 (0)