Modified:

- Plugins and settings is now in beta.

Implemented:
- Show the count of the pending processes into the status.
This commit is contained in:
vorotamoroz
2022-01-11 13:17:35 +09:00
parent 5bb8b2567b
commit ebcb059d99
8 changed files with 43 additions and 7 deletions

View File

@@ -75,6 +75,8 @@ Synchronization status is shown in statusbar.
- ⚠ Error occurred. - ⚠ Error occurred.
- ↑ Uploaded pieces - ↑ Uploaded pieces
- ↓ Downloaded pieces - ↓ Downloaded pieces
- ⏳ Count of the pending process
If you have deleted or renamed files, please wait until this disappears.
# More supplements # More supplements

View File

@@ -78,6 +78,8 @@ Self-hosted LiveSync用にWebClipperも作りました。Chrome Web Storeから
- ⚠ エラーが発生しています - ⚠ エラーが発生しています
- ↑ 送信したデータ数 - ↑ 送信したデータ数
- ↓ 受信したデータ数 - ↓ 受信したデータ数
- ⏳ 保留している処理の数です
ファイルを削除したりリネームした場合、この表示が消えるまでお待ちください。
# さらなる補足 # さらなる補足
- ファイルは同期された後、タイムスタンプを比較して新しければいったん新しい方で上書きされます。その後、衝突が発生したかによって、マージが行われます。 - ファイルは同期された後、タイムスタンプを比較して新しければいったん新しい方で上書きされます。その後、衝突が発生したかによって、マージが行われます。

View File

@@ -1,7 +1,7 @@
{ {
"id": "obsidian-livesync", "id": "obsidian-livesync",
"name": "Self-hosted LiveSync", "name": "Self-hosted LiveSync",
"version": "0.4.1", "version": "0.5.0",
"minAppVersion": "0.9.12", "minAppVersion": "0.9.12",
"description": "Community implementation of self-hosted livesync. Reflect your vault changes to some other devices immediately. Please make sure to disable other synchronize solutions to avoid content corruption or duplication.", "description": "Community implementation of self-hosted livesync. Reflect your vault changes to some other devices immediately. Please make sure to disable other synchronize solutions to avoid content corruption or duplication.",
"author": "vorotamoroz", "author": "vorotamoroz",

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "obsidian-livesync", "name": "obsidian-livesync",
"version": "0.4.1", "version": "0.5.0",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "obsidian-livesync", "name": "obsidian-livesync",
"version": "0.4.1", "version": "0.5.0",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"diff-match-patch": "^1.0.5", "diff-match-patch": "^1.0.5",

View File

@@ -1,6 +1,6 @@
{ {
"name": "obsidian-livesync", "name": "obsidian-livesync",
"version": "0.4.1", "version": "0.5.0",
"description": "Reflect your vault changes to some other devices immediately. Please make sure to disable other synchronize solutions to avoid content corruption or duplication.", "description": "Reflect your vault changes to some other devices immediately. Please make sure to disable other synchronize solutions to avoid content corruption or duplication.",
"main": "main.js", "main": "main.js",
"scripts": { "scripts": {

View File

@@ -811,7 +811,7 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
// With great respect, thank you TfTHacker! // With great respect, thank you TfTHacker!
// refered: https://github.com/TfTHacker/obsidian42-brat/blob/main/src/features/BetaPlugins.ts // refered: https://github.com/TfTHacker/obsidian42-brat/blob/main/src/features/BetaPlugins.ts
const containerPluginSettings = containerEl.createDiv(); const containerPluginSettings = containerEl.createDiv();
containerPluginSettings.createEl("h3", { text: "Plugins and settings (bleeding edge)" }); containerPluginSettings.createEl("h3", { text: "Plugins and settings (beta)" });
const updateDisabledOfDeviceAndVaultName = () => { const updateDisabledOfDeviceAndVaultName = () => {
vaultName.setDisabled(this.plugin.settings.autoSweepPlugins || this.plugin.settings.autoSweepPluginsPeriodic); vaultName.setDisabled(this.plugin.settings.autoSweepPlugins || this.plugin.settings.autoSweepPluginsPeriodic);

View File

@@ -18,7 +18,7 @@ import {
diff_result, diff_result,
FLAGMD_REDFLAG, FLAGMD_REDFLAG,
} from "./types"; } from "./types";
import { base64ToString, arrayBufferToBase64, base64ToArrayBuffer, isValidPath, versionNumberString2Number, id2path, path2id, runWithLock, shouldBeIgnored } from "./utils"; import { base64ToString, arrayBufferToBase64, base64ToArrayBuffer, isValidPath, versionNumberString2Number, id2path, path2id, runWithLock, shouldBeIgnored, getProcessingCounts, setLockNotifier } from "./utils";
import { Logger, setLogger } from "./logger"; import { Logger, setLogger } from "./logger";
import { LocalPouchDB } from "./LocalPouchDB"; import { LocalPouchDB } from "./LocalPouchDB";
import { LogDisplayModal } from "./LogDisplayModal"; import { LogDisplayModal } from "./LogDisplayModal";
@@ -205,6 +205,9 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
}); });
this.triggerRealizeSettingSyncMode = debounce(this.triggerRealizeSettingSyncMode.bind(this), 1000); this.triggerRealizeSettingSyncMode = debounce(this.triggerRealizeSettingSyncMode.bind(this), 1000);
this.triggerCheckPluginUpdate = debounce(this.triggerCheckPluginUpdate.bind(this), 3000); this.triggerCheckPluginUpdate = debounce(this.triggerCheckPluginUpdate.bind(this), 3000);
setLockNotifier(() => {
this.refreshStatusText();
});
} }
onunload() { onunload() {
this.localDatabase.onunload(); this.localDatabase.onunload();
@@ -787,7 +790,9 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
waiting = " " + this.batchFileChange.map((e) => "🛫").join(""); waiting = " " + this.batchFileChange.map((e) => "🛫").join("");
waiting = waiting.replace(/(🛫){10}/g, "🚀"); waiting = waiting.replace(/(🛫){10}/g, "🚀");
} }
const message = `Sync:${w}${sent}${arrived}${waiting}`; const procs = getProcessingCounts();
const procsDisp = procs==0?"":`${procs}`;
const message = `Sync:${w}${sent}${arrived}${waiting}${procsDisp}`;
this.setStatusBarText(message); this.setStatusBarText(message);
} }
setStatusBarText(message: string) { setStatusBarText(message: string) {

View File

@@ -121,7 +121,28 @@ function objectToKey(key: any): string {
const keys = Object.keys(key).sort((a, b) => a.localeCompare(b)); const keys = Object.keys(key).sort((a, b) => a.localeCompare(b));
return keys.map((e) => e + objectToKey(key[e])).join(":"); return keys.map((e) => e + objectToKey(key[e])).join(":");
} }
export function getProcessingCounts() {
let count = 0;
for (const v in pendingProcs) {
count += pendingProcs[v].length;
}
count += runningProcs.length;
return count;
}
let externalNotifier: () => void = () => {};
let notifyTimer: number = null;
export function setLockNotifier(fn: () => void) {
externalNotifier = fn;
}
function notifyLock() {
if (notifyTimer != null) {
window.clearTimeout(notifyTimer);
}
notifyTimer = window.setTimeout(() => {
externalNotifier();
}, 100);
}
// Just run async/await as like transacion ISOLATION SERIALIZABLE // Just run async/await as like transacion ISOLATION SERIALIZABLE
export function runWithLock<T>(key: unknown, ignoreWhenRunning: boolean, proc: () => Promise<T>): Promise<T> { export function runWithLock<T>(key: unknown, ignoreWhenRunning: boolean, proc: () => Promise<T>): Promise<T> {
// Logger(`Lock:${key}:enter`, LOG_LEVEL.VERBOSE); // Logger(`Lock:${key}:enter`, LOG_LEVEL.VERBOSE);
@@ -130,11 +151,13 @@ export function runWithLock<T>(key: unknown, ignoreWhenRunning: boolean, proc: (
if (typeof pendingProcs[lockKey] === "undefined") { if (typeof pendingProcs[lockKey] === "undefined") {
//simply unlock //simply unlock
runningProcs.remove(lockKey); runningProcs.remove(lockKey);
notifyLock();
// Logger(`Lock:${lockKey}:released`, LOG_LEVEL.VERBOSE); // Logger(`Lock:${lockKey}:released`, LOG_LEVEL.VERBOSE);
} else { } else {
Logger(`Lock:${lockKey}:left ${pendingProcs[lockKey].length}`, LOG_LEVEL.VERBOSE); Logger(`Lock:${lockKey}:left ${pendingProcs[lockKey].length}`, LOG_LEVEL.VERBOSE);
let nextProc = null; let nextProc = null;
nextProc = pendingProcs[lockKey].shift(); nextProc = pendingProcs[lockKey].shift();
notifyLock();
if (nextProc) { if (nextProc) {
// left some // left some
nextProc() nextProc()
@@ -145,6 +168,7 @@ export function runWithLock<T>(key: unknown, ignoreWhenRunning: boolean, proc: (
.finally(() => { .finally(() => {
if (pendingProcs && lockKey in pendingProcs && pendingProcs[lockKey].length == 0) { if (pendingProcs && lockKey in pendingProcs && pendingProcs[lockKey].length == 0) {
delete pendingProcs[lockKey]; delete pendingProcs[lockKey];
notifyLock();
} }
queueMicrotask(() => { queueMicrotask(() => {
handleNextProcs(); handleNextProcs();
@@ -153,6 +177,7 @@ export function runWithLock<T>(key: unknown, ignoreWhenRunning: boolean, proc: (
} else { } else {
if (pendingProcs && lockKey in pendingProcs && pendingProcs[lockKey].length == 0) { if (pendingProcs && lockKey in pendingProcs && pendingProcs[lockKey].length == 0) {
delete pendingProcs[lockKey]; delete pendingProcs[lockKey];
notifyLock();
} }
} }
} }
@@ -189,10 +214,12 @@ export function runWithLock<T>(key: unknown, ignoreWhenRunning: boolean, proc: (
}); });
pendingProcs[lockKey].push(subproc); pendingProcs[lockKey].push(subproc);
notifyLock();
// Logger(`Lock:${lockKey}:queud:left${pendingProcs[lockKey].length}`, LOG_LEVEL.VERBOSE); // Logger(`Lock:${lockKey}:queud:left${pendingProcs[lockKey].length}`, LOG_LEVEL.VERBOSE);
return responder; return responder;
} else { } else {
runningProcs.push(lockKey); runningProcs.push(lockKey);
notifyLock();
// Logger(`Lock:${lockKey}:aqquired`, LOG_LEVEL.VERBOSE); // Logger(`Lock:${lockKey}:aqquired`, LOG_LEVEL.VERBOSE);
return new Promise((res, rej) => { return new Promise((res, rej) => {
proc() proc()