mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-25 14:28:51 +08:00
feat(core): support better battery save mode (#13383)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Introduced a Document Summary module, enabling live and cached document summaries with cloud revalidation. * Added a feature flag for enabling battery save mode. * Added explicit pause and resume controls for sync operations, accessible via UI events and programmatically. * **Improvements** * Enhanced sync and indexing logic to support pausing, resuming, and battery save mode, with improved job prioritization. * Updated navigation and preview components to use the new document summary service and improved priority handling. * Improved logging and state reporting for sync and indexing processes. * Refined backlink handling with reactive loading states and cloud revalidation. * Replaced backlink and link management to use a new dedicated document links service. * Enhanced workspace engine to conditionally enable battery save mode based on feature flags and workspace flavor. * **Bug Fixes** * Removed unnecessary debug console logs from various components for cleaner output. * **Refactor** * Replaced battery save mode methods with explicit pause/resume methods throughout the app and services. * Modularized and streamlined document summary and sync-related code for better maintainability. * Restructured backlink components to improve visibility handling and data fetching. * Simplified and improved document backlink data fetching with retry and loading state management. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -712,7 +712,7 @@ export class DocSyncPeer {
|
||||
while (true) {
|
||||
throwIfAborted(signal);
|
||||
|
||||
const docId = await this.status.jobDocQueue.asyncPop(signal);
|
||||
const docId = await this.status.jobDocQueue.asyncPop(undefined, signal);
|
||||
|
||||
while (true) {
|
||||
// batch process jobs for the same doc
|
||||
|
||||
@@ -36,6 +36,8 @@ import { crawlingDocData } from './crawler';
|
||||
export type IndexerPreferOptions = 'local' | 'remote';
|
||||
|
||||
export interface IndexerSyncState {
|
||||
paused: boolean;
|
||||
batterySaveMode: boolean;
|
||||
/**
|
||||
* Number of documents currently in the indexing queue
|
||||
*/
|
||||
@@ -167,6 +169,14 @@ export class IndexerSyncImpl implements IndexerSync {
|
||||
this.status.disableBatterySaveMode();
|
||||
}
|
||||
|
||||
pauseSync() {
|
||||
this.status.pauseSync();
|
||||
}
|
||||
|
||||
resumeSync() {
|
||||
this.status.resumeSync();
|
||||
}
|
||||
|
||||
start() {
|
||||
if (this.abort) {
|
||||
this.abort.abort(MANUALLY_STOP);
|
||||
@@ -324,6 +334,7 @@ export class IndexerSyncImpl implements IndexerSync {
|
||||
const docId = await this.status.acceptJob(signal);
|
||||
|
||||
if (docId === this.rootDocId) {
|
||||
console.log('[indexer] start indexing root doc', docId);
|
||||
// #region crawl root doc
|
||||
for (const [docId, { title }] of this.status.docsInRootDoc) {
|
||||
const existingDoc = this.status.docsInIndexer.get(docId);
|
||||
@@ -401,6 +412,7 @@ export class IndexerSyncImpl implements IndexerSync {
|
||||
// doc is deleted, just skip
|
||||
continue;
|
||||
}
|
||||
console.log('[indexer] start indexing doc', docId);
|
||||
const docYDoc = new YDoc({ guid: docId });
|
||||
applyUpdate(docYDoc, docBin.bin);
|
||||
|
||||
@@ -454,6 +466,8 @@ export class IndexerSyncImpl implements IndexerSync {
|
||||
// #endregion
|
||||
}
|
||||
|
||||
console.log('[indexer] complete job', docId);
|
||||
|
||||
this.status.completeJob();
|
||||
}
|
||||
} finally {
|
||||
@@ -619,10 +633,11 @@ class IndexerSyncStatus {
|
||||
currentJob: string | null = null;
|
||||
errorMessage: string | null = null;
|
||||
statusUpdatedSubject$ = new Subject<string | true>();
|
||||
batterySaveMode: {
|
||||
paused: {
|
||||
promise: Promise<void>;
|
||||
resolve: () => void;
|
||||
} | null = null;
|
||||
batterySaveMode: boolean = false;
|
||||
|
||||
state$ = new Observable<IndexerSyncState>(subscribe => {
|
||||
const next = () => {
|
||||
@@ -632,6 +647,8 @@ class IndexerSyncStatus {
|
||||
total: 0,
|
||||
errorMessage: this.errorMessage,
|
||||
completed: true,
|
||||
batterySaveMode: this.batterySaveMode,
|
||||
paused: this.paused !== null,
|
||||
});
|
||||
} else {
|
||||
subscribe.next({
|
||||
@@ -639,6 +656,8 @@ class IndexerSyncStatus {
|
||||
total: this.docsInRootDoc.size + 1,
|
||||
errorMessage: this.errorMessage,
|
||||
completed: this.rootDocReady && this.jobs.length() === 0,
|
||||
batterySaveMode: this.batterySaveMode,
|
||||
paused: this.paused !== null,
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -697,10 +716,14 @@ class IndexerSyncStatus {
|
||||
}
|
||||
|
||||
async acceptJob(abort?: AbortSignal) {
|
||||
if (this.batterySaveMode) {
|
||||
await this.batterySaveMode.promise;
|
||||
if (this.paused) {
|
||||
await this.paused.promise;
|
||||
}
|
||||
const job = await this.jobs.asyncPop(abort);
|
||||
const job = await this.jobs.asyncPop(
|
||||
// if battery save mode is enabled, only accept jobs with priority > 1; otherwise accept all jobs
|
||||
this.batterySaveMode ? 1 : undefined,
|
||||
abort
|
||||
);
|
||||
this.currentJob = job;
|
||||
this.statusUpdatedSubject$.next(job);
|
||||
return job;
|
||||
@@ -728,12 +751,33 @@ class IndexerSyncStatus {
|
||||
if (this.batterySaveMode) {
|
||||
return;
|
||||
}
|
||||
this.batterySaveMode = Promise.withResolvers();
|
||||
this.batterySaveMode = true;
|
||||
this.statusUpdatedSubject$.next(true);
|
||||
}
|
||||
|
||||
disableBatterySaveMode() {
|
||||
this.batterySaveMode?.resolve();
|
||||
this.batterySaveMode = null;
|
||||
if (!this.batterySaveMode) {
|
||||
return;
|
||||
}
|
||||
this.batterySaveMode = false;
|
||||
this.statusUpdatedSubject$.next(true);
|
||||
}
|
||||
|
||||
pauseSync() {
|
||||
if (this.paused) {
|
||||
return;
|
||||
}
|
||||
this.paused = Promise.withResolvers();
|
||||
this.statusUpdatedSubject$.next(true);
|
||||
}
|
||||
|
||||
resumeSync() {
|
||||
if (!this.paused) {
|
||||
return;
|
||||
}
|
||||
this.paused.resolve();
|
||||
this.paused = null;
|
||||
this.statusUpdatedSubject$.next(true);
|
||||
}
|
||||
|
||||
reset() {
|
||||
@@ -745,6 +789,8 @@ class IndexerSyncStatus {
|
||||
this.rootDoc = new YDoc();
|
||||
this.rootDocReady = false;
|
||||
this.currentJob = null;
|
||||
this.batterySaveMode = false;
|
||||
this.paused = null;
|
||||
this.statusUpdatedSubject$.next(true);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user