Skip to content

Commit 7f506c7

Browse files
committed
fix: don't reschedule auto commit-and-sync too often
close #875
1 parent fe734b7 commit 7f506c7

File tree

4 files changed

+78
-51
lines changed

4 files changed

+78
-51
lines changed

src/automaticsManager.ts

Lines changed: 61 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -36,24 +36,18 @@ export default class AutomaticsManager {
3636
this.plugin.settings.differentIntervalCommitAndPush &&
3737
this.plugin.settings.autoPushInterval > 0
3838
) {
39-
const now = new Date();
40-
41-
const diff =
42-
this.plugin.settings.autoPushInterval -
43-
Math.round(
44-
(now.getTime() - lastAutos.push.getTime()) / 1000 / 60
45-
);
46-
this.startAutoPush(diff <= 0 ? 0 : diff);
39+
const diff = this.diff(
40+
this.plugin.settings.autoPushInterval,
41+
lastAutos.push
42+
);
43+
this.startAutoPush(diff);
4744
}
4845
if (this.plugin.settings.autoPullInterval > 0) {
49-
const now = new Date();
50-
51-
const diff =
52-
this.plugin.settings.autoPullInterval -
53-
Math.round(
54-
(now.getTime() - lastAutos.pull.getTime()) / 1000 / 60
55-
);
56-
this.startAutoPull(diff <= 0 ? 0 : diff);
46+
const diff = this.diff(
47+
this.plugin.settings.autoPullInterval,
48+
lastAutos.pull
49+
);
50+
this.startAutoPull(diff);
5751
}
5852
}
5953

@@ -96,37 +90,30 @@ export default class AutomaticsManager {
9690
}
9791

9892
/**
99-
* Starts the debouncer and timer with the correct remaining time.
93+
* Starts the auto commit-and-sync with the correct remaining time.
10094
*
10195
* Additionally, if `setLastSaveToLastCommit` is enabled, the last auto commit-and-sync
10296
* is set to the last commit time.
103-
*
104-
* Should be called when the latest commit time is changed. E.g. after a commit or pull.
10597
*/
106-
async setUpAutoCommitAndSync() {
98+
private async setUpAutoCommitAndSync() {
10799
if (this.plugin.settings.setLastSaveToLastCommit) {
108100
this.clearAutoCommitAndSync();
109101
const lastCommitDate =
110102
await this.plugin.gitManager.getLastCommitTime();
111103
if (lastCommitDate) {
112-
this.plugin.localStorage.setLastAutoBackup(
113-
lastCommitDate.toString()
114-
);
104+
this.saveLastAuto(lastCommitDate, "backup");
115105
}
116106
}
117107

118108
if (!this.timeoutIDCommitAndSync && !this.plugin.autoCommitDebouncer) {
119109
const lastAutos = this.loadLastAuto();
120110

121111
if (this.plugin.settings.autoSaveInterval > 0) {
122-
const now = new Date();
123-
124-
const diff =
125-
this.plugin.settings.autoSaveInterval -
126-
Math.round(
127-
(now.getTime() - lastAutos.backup.getTime()) / 1000 / 60
128-
);
129-
this.startAutoCommitAndSync(diff <= 0 ? 0 : diff);
112+
const diff = this.diff(
113+
this.plugin.settings.autoSaveInterval,
114+
lastAutos.backup
115+
);
116+
this.startAutoCommitAndSync(diff);
130117
}
131118
}
132119
}
@@ -153,19 +140,42 @@ export default class AutomaticsManager {
153140
}
154141
}
155142

156-
// this.plugin is used for both auto commit-and-sync and commit only
143+
// This is used for both auto commit-and-sync and commit only
157144
private doAutoCommitAndSync(): void {
158145
this.plugin.promiseQueue.addTask(
159-
() => {
146+
async () => {
147+
// Re-check if the auto commit should run now or be postponed,
148+
// because the last commit time has changed
149+
if (this.plugin.settings.setLastSaveToLastCommit) {
150+
const lastCommitDate =
151+
await this.plugin.gitManager.getLastCommitTime();
152+
if (lastCommitDate) {
153+
this.saveLastAuto(lastCommitDate, "backup");
154+
const diff = this.diff(
155+
this.plugin.settings.autoSaveInterval,
156+
lastCommitDate
157+
);
158+
if (diff > 0) {
159+
this.startAutoCommitAndSync(diff);
160+
// Return false to mark the next iteration
161+
// already being scheduled
162+
return false;
163+
}
164+
}
165+
}
160166
if (this.plugin.settings.differentIntervalCommitAndPush) {
161-
return this.plugin.commit({ fromAuto: true });
167+
await this.plugin.commit({ fromAuto: true });
162168
} else {
163-
return this.plugin.commitAndSync(true);
169+
await this.plugin.commitAndSync(true);
164170
}
171+
return true;
165172
},
166-
() => {
167-
this.saveLastAuto(new Date(), "backup");
168-
this.startAutoCommitAndSync();
173+
(schedule) => {
174+
// Don't schedule if the next iteration is already scheduled
175+
if (schedule !== false) {
176+
this.saveLastAuto(new Date(), "backup");
177+
this.startAutoCommitAndSync();
178+
}
169179
}
170180
);
171181
}
@@ -238,4 +248,17 @@ export default class AutomaticsManager {
238248
}
239249
return false;
240250
}
251+
252+
/**
253+
* Calculates the minutes until the next auto action. >= 0
254+
*
255+
* This is done by the difference between the setting and the time since the last auto action, but at least 0.
256+
*/
257+
private diff(setting: number, lastAuto: Date) {
258+
const now = new Date();
259+
const diff =
260+
setting -
261+
Math.round((now.getTime() - lastAuto.getTime()) / 1000 / 60);
262+
return Math.max(0, diff);
263+
}
241264
}

src/main.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,6 @@ export default class ObsidianGit extends Plugin {
706706
if (!(await this.isAllInitialized())) return;
707707

708708
const filesUpdated = await this.pull();
709-
await this.automaticsManager.setUpAutoCommitAndSync();
710709
if (filesUpdated === false) {
711710
return;
712711
}
@@ -909,7 +908,6 @@ export default class ObsidianGit extends Plugin {
909908
roughly = true;
910909
committedFiles = changedFiles.length;
911910
}
912-
await this.automaticsManager.setUpAutoCommitAndSync();
913911
this.displayMessage(
914912
`Committed${roughly ? " approx." : ""} ${committedFiles} ${
915913
committedFiles == 1 ? "file" : "files"

src/promiseQueue.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type ObsidianGit from "./main";
33
export class PromiseQueue {
44
private tasks: {
55
task: () => Promise<unknown>;
6-
onFinished: () => void;
6+
onFinished: (res: unknown) => void;
77
}[] = [];
88

99
constructor(private readonly plugin: ObsidianGit) {}
@@ -14,7 +14,10 @@ export class PromiseQueue {
1414
* @param task The task to add.
1515
* @param onFinished A callback that is called when the task is finished. Both on success and on error.
1616
*/
17-
addTask(task: () => Promise<unknown>, onFinished?: () => void): void {
17+
addTask<T>(
18+
task: () => Promise<T>,
19+
onFinished?: (res: T | undefined) => void
20+
): void {
1821
this.tasks.push({ task, onFinished: onFinished ?? (() => {}) });
1922
if (this.tasks.length === 1) {
2023
this.handleTask();
@@ -24,13 +27,19 @@ export class PromiseQueue {
2427
private handleTask(): void {
2528
if (this.tasks.length > 0) {
2629
const item = this.tasks[0];
27-
item.task()
28-
.catch((e) => this.plugin.displayError(e))
29-
.finally(() => {
30-
item.onFinished();
30+
item.task().then(
31+
(res) => {
32+
item.onFinished(res);
3133
this.tasks.shift();
3234
this.handleTask();
33-
});
35+
},
36+
(e) => {
37+
this.plugin.displayError(e);
38+
item.onFinished(undefined);
39+
this.tasks.shift();
40+
this.handleTask();
41+
}
42+
);
3443
}
3544
}
3645

src/ui/sourceControl/sourceControl.svelte

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,7 @@
9191
plugin.promiseQueue.addTask(() =>
9292
plugin.gitManager
9393
.commit({ message: commitMessage })
94-
.then(async () => {
95-
commitMessage = plugin.settings.commitMessage;
96-
await plugin.automaticsManager.setUpAutoCommitAndSync();
97-
})
94+
.then(() => (commitMessage = plugin.settings.commitMessage))
9895
.finally(triggerRefresh)
9996
);
10097
}

0 commit comments

Comments
 (0)