Skip to content

Commit

Permalink
Do not update query when it has no subscriber
Browse files Browse the repository at this point in the history
  • Loading branch information
aguspdana committed Nov 26, 2023
1 parent cecf84c commit 58b49fc
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 11 deletions.
21 changes: 21 additions & 0 deletions src/query.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,24 @@ test('The query should be destroyed after not subscribed for `delete_after` mill
await sleep(15);
expect(count().get()).toMatchObject({ status: 'finished', value: 5 });
})

test("Should not update query when it has no subscriber", async () => {
let source = 1;
const count = query(
async () => {
await sleep(2);
source += 2;
return source;
},
{
update_every: 5,
remove_after: 25,
}
);

expect(count().get()).toMatchObject({ status: 'pending' });
await sleep(3);
expect(count().get()).toMatchObject({ status: 'finished', value: 3 });
await sleep(15);
expect(count().get()).toMatchObject({ status: 'finished', value: 3 });
});
31 changes: 20 additions & 11 deletions src/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,19 @@ export class Query<P extends Param, T> {
this.subscribers_count = count;
if (count === 0) {
this.schedule_removal();
// TODO: If subscribers count is 0 for awhile maybe cancel scheduled update.
return;
}
this.cancel_removal();
const isStale = Date.now() - this.last_update > this.options.update_every;
if (isStale && !this.is_loading) {
this.cancel_removal?.();
const is_stale = Date.now() - this.last_update_ts > this.options.update_every;
if (is_stale && !this.is_loading) {
this.load();
}
}
);
private options: QueryOptions;
private cancel_removal: (() => void) | null = null;
private cancel_update: (() => void) | null = null;
private last_update = Date.now();
private last_update_ts = Date.now();
private first_load = false;
private is_loading = false;
private load_id = 0;
Expand All @@ -51,7 +50,6 @@ export class Query<P extends Param, T> {
}

get() {
// TODO: Schedule for update if there's no subscriber and it's not scheduled.
if (!this.first_load) {
this.load();
}
Expand Down Expand Up @@ -79,24 +77,35 @@ export class Query<P extends Param, T> {
}

this.is_loading = false;
this.last_update = Date.now();
this.last_update_ts = Date.now();
this.schedule_update();
}

private schedule_removal(duration = this.options.remove_after) {
if (this.cancel_removal === null) {
this.cancel_removal = schedule(this.remove_from_registry.bind(this), duration);
const cancel = schedule(this.remove_from_registry.bind(this), duration);
this.cancel_removal = () => {
cancel();
this.cancel_removal = null;
};
}
}

private schedule_update() {
if (this.subscribers_count !== 0 && this.cancel_update === null) {
this.cancel_update = schedule(this.load.bind(this), this.options.update_every);
const cancel = schedule(() => {
if (this.subscribers_count !== 0) {
this.load();
}
}, this.options.update_every);
this.cancel_update = () => {
cancel();
this.cancel_update = null;
};
}
}

select<V>(selector: Selector<QueryState<T>, V>): V {
// TODO: Schedule for update if there's no subscriber and it's not scheduled.
if (!this.first_load) {
this.load();
}
Expand All @@ -110,7 +119,7 @@ export class Query<P extends Param, T> {
this.store.set({ status: 'finished', value });

this.is_loading = false;
this.last_update = Date.now();
this.last_update_ts = Date.now();
this.schedule_update();
}
}
Expand Down

0 comments on commit 58b49fc

Please sign in to comment.