diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index e981134d..402dc1d7 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -2981,6 +2981,10 @@ export class TelegramClient extends BaseTelegramClient { protected _updLock: AsyncLock protected _pts: number protected _date: number + protected _seq: number + protected _oldPts: number + protected _oldDate: number + protected _oldSeq: number protected _cpts: Record protected _cptsMod: Record constructor(opts: BaseTelegramClient.Options) { diff --git a/packages/client/src/methods/updates.ts b/packages/client/src/methods/updates.ts index 8b3a139b..19bcb363 100644 --- a/packages/client/src/methods/updates.ts +++ b/packages/client/src/methods/updates.ts @@ -27,6 +27,12 @@ interface UpdatesState { _date: number _seq: number + // old values of the updates statej (i.e. as in DB) + // used to avoid redundant storage calls + _oldPts: number + _oldDate: number + _oldSeq: number + _cpts: Record _cptsMod: Record } @@ -70,11 +76,11 @@ export async function _fetchUpdatesState(this: TelegramClient): Promise { export async function _loadStorage(this: TelegramClient): Promise { // load updates state from the session await this.storage.load?.() - const state = await this.storage.getCommonPts() + const state = await this.storage.getUpdatesState() if (state) { - this._pts = state[0] - this._date = state[1] - this._seq = state[2] + this._pts = this._oldPts = state[0] + this._date = this._oldDate = state[1] + this._seq = this._oldSeq = state[2] } // if no state, don't bother initializing properties // since that means that there is no authorization, @@ -96,7 +102,19 @@ export async function _saveStorage(this: TelegramClient): Promise { try { // before any authorization pts will be undefined if (this._pts !== undefined) { - await this.storage.setCommonPts([this._pts, this._date, this._seq]) + // if old* value is not available, assume it has changed. + if (this._oldPts === undefined || this._oldPts !== this._pts) + await this.storage.setUpdatesPts(this._pts) + if (this._oldDate === undefined || this._oldDate !== this._date) + await this.storage.setUpdatesDate(this._date) + if (this._oldSeq === undefined || this._oldSeq !== this._seq) + await this.storage.setUpdatesSeq(this._seq) + + // update old* values + this._oldPts = this._pts + this._oldDate = this._date + this._oldSeq = this._seq + await this.storage.setManyChannelPts(this._cptsMod) this._cptsMod = {} } @@ -426,7 +444,12 @@ export function _handleUpdate( // https://t.me/tdlibchat/5843 const nextLocalSeq = this._seq + 1 - debug('received %s (seq_start=%d, seq_end=%d)', update._, seqStart, update.seq) + debug( + 'received %s (seq_start=%d, seq_end=%d)', + update._, + seqStart, + update.seq + ) if (nextLocalSeq > seqStart) // "the updates were already applied, and must be ignored" diff --git a/packages/core/src/storage/abstract.ts b/packages/core/src/storage/abstract.ts index 7a0a6482..bf11c343 100644 --- a/packages/core/src/storage/abstract.ts +++ b/packages/core/src/storage/abstract.ts @@ -103,17 +103,28 @@ export interface ITelegramStorage { getPeerByPhone(phone: string): MaybeAsync /** - * Get common `pts`, `date` and `seq` values (if available) + * Get updates state (if available), represented as a tuple + * containing: `pts, date, seq` */ - getCommonPts(): MaybeAsync<[number, number, number] | null> + getUpdatesState(): MaybeAsync<[number, number, number] | null> + + /** + * Set common `pts` value + */ + setUpdatesPts(val: number): MaybeAsync + /** + * Set updates `date` value + */ + setUpdatesDate(val: number): MaybeAsync + /** + * Set updates `seq` value + */ + setUpdatesSeq(val: number): MaybeAsync + /** * Get channel `pts` value */ getChannelPts(entityId: number): MaybeAsync - /** - * Set common `pts`, `date` and `seq` values - */ - setCommonPts(val: [number, number, number]): MaybeAsync /** * Set channels `pts` values in batch. * Storage is supposed to replace stored channel `pts` values