1
0
This commit is contained in:
Zef Hemel 2023-02-28 11:13:18 +01:00
parent 520b5e91d6
commit ece4177e11
5 changed files with 57 additions and 6 deletions

View File

@ -10,7 +10,7 @@ Deno.test("Test store", async () => {
const primary = new DiskSpacePrimitives(primaryPath); const primary = new DiskSpacePrimitives(primaryPath);
const secondary = new DiskSpacePrimitives(secondaryPath); const secondary = new DiskSpacePrimitives(secondaryPath);
const statusMap = new Map<string, SyncStatusItem>(); const statusMap = new Map<string, SyncStatusItem>();
const sync = new SpaceSync(primary, secondary, statusMap); const sync = new SpaceSync(primary, secondary, statusMap, {});
// Write one page to primary // Write one page to primary
await primary.writeFile("index", "utf8", "Hello"); await primary.writeFile("index", "utf8", "Hello");
@ -129,6 +129,7 @@ Deno.test("Test store", async () => {
secondary, secondary,
ternary, ternary,
new Map<string, SyncStatusItem>(), new Map<string, SyncStatusItem>(),
{},
); );
console.log( console.log(
"N ops", "N ops",
@ -137,9 +138,25 @@ Deno.test("Test store", async () => {
await sleep(2); await sleep(2);
assertEquals(await sync2.syncFiles(SpaceSync.primaryConflictResolver), 0); assertEquals(await sync2.syncFiles(SpaceSync.primaryConflictResolver), 0);
// I had to look up what follows ternary (https://english.stackexchange.com/questions/25116/what-follows-next-in-the-sequence-unary-binary-ternary)
const quaternaryPath = await Deno.makeTempDir();
const quaternary = new DiskSpacePrimitives(quaternaryPath);
const sync3 = new SpaceSync(
secondary,
quaternary,
new Map<string, SyncStatusItem>(),
{
excludePrefixes: ["index"],
},
);
const selectingOps = await sync3.syncFiles(SpaceSync.primaryConflictResolver);
assertEquals(selectingOps, 1);
await Deno.remove(primaryPath, { recursive: true }); await Deno.remove(primaryPath, { recursive: true });
await Deno.remove(secondaryPath, { recursive: true }); await Deno.remove(secondaryPath, { recursive: true });
await Deno.remove(ternaryPath, { recursive: true }); await Deno.remove(ternaryPath, { recursive: true });
await Deno.remove(quaternaryPath, { recursive: true });
async function doSync() { async function doSync() {
await sleep(); await sleep();

View File

@ -20,14 +20,25 @@ class ConsoleLogger implements Logger {
} }
} }
export type SyncOptions = {
logger?: Logger;
excludePrefixes?: string[];
};
// Implementation of this algorithm https://unterwaditzer.net/2016/sync-algorithm.html // Implementation of this algorithm https://unterwaditzer.net/2016/sync-algorithm.html
export class SpaceSync { export class SpaceSync {
logger: ConsoleLogger;
excludePrefixes: string[];
constructor( constructor(
private primary: SpacePrimitives, private primary: SpacePrimitives,
private secondary: SpacePrimitives, private secondary: SpacePrimitives,
readonly snapshot: Map<string, SyncStatusItem>, readonly snapshot: Map<string, SyncStatusItem>,
readonly logger: Logger = new ConsoleLogger(), readonly options: SyncOptions,
) {} ) {
this.logger = options.logger || new ConsoleLogger();
this.excludePrefixes = options.excludePrefixes || [];
}
async syncFiles( async syncFiles(
conflictResolver: ( conflictResolver: (
@ -100,6 +111,13 @@ export class SpaceSync {
// console.log("Syncing", name, primaryHash, secondaryHash); // console.log("Syncing", name, primaryHash, secondaryHash);
let operations = 0; let operations = 0;
// Check if not matching one of the excluded prefixes
for (const prefix of this.excludePrefixes) {
if (name.startsWith(prefix)) {
return operations;
}
}
if ( if (
primaryHash !== undefined && secondaryHash === undefined && primaryHash !== undefined && secondaryHash === undefined &&
!this.snapshot.has(name) !this.snapshot.has(name)

View File

@ -3,7 +3,6 @@ import type { SyncEndpoint } from "../../plug-api/silverbullet-syscall/sync.ts";
import { SpaceSync, SyncStatusItem } from "../spaces/sync.ts"; import { SpaceSync, SyncStatusItem } from "../spaces/sync.ts";
import { HttpSpacePrimitives } from "../spaces/http_space_primitives.ts"; import { HttpSpacePrimitives } from "../spaces/http_space_primitives.ts";
import { SpacePrimitives } from "../spaces/space_primitives.ts"; import { SpacePrimitives } from "../spaces/space_primitives.ts";
import { race, timeout } from "../async_util.ts";
export function syncSyscalls( export function syncSyscalls(
localSpace: SpacePrimitives, localSpace: SpacePrimitives,
@ -122,8 +121,11 @@ export function syncSyscalls(
localSpace, localSpace,
remoteSpace, remoteSpace,
syncStatusMap, syncStatusMap,
// Log to the "sync" plug sandbox {
system.loadedPlugs.get("sync")!.sandbox!, excludePrefixes: endpoint.excludePrefixes,
// Log to the "sync" plug sandbox
logger: system.loadedPlugs.get("sync")!.sandbox!,
},
); );
return { spaceSync, remoteSpace }; return { spaceSync, remoteSpace };
} }

View File

@ -5,6 +5,7 @@ export type SyncEndpoint = {
url: string; url: string;
user?: string; user?: string;
password?: string; password?: string;
excludePrefixes?: string[];
}; };
// Perform a sync with the server, based on the given status (to be persisted) // Perform a sync with the server, based on the given status (to be persisted)

View File

@ -1,6 +1,7 @@
import { store } from "$sb/plugos-syscall/mod.ts"; import { store } from "$sb/plugos-syscall/mod.ts";
import { editor, space, sync, system } from "$sb/silverbullet-syscall/mod.ts"; import { editor, space, sync, system } from "$sb/silverbullet-syscall/mod.ts";
import type { SyncEndpoint } from "$sb/silverbullet-syscall/sync.ts"; import type { SyncEndpoint } from "$sb/silverbullet-syscall/sync.ts";
import { readSetting } from "$sb/lib/settings_page.ts";
export async function configureCommand() { export async function configureCommand() {
const url = await editor.prompt( const url = await editor.prompt(
@ -160,6 +161,8 @@ export async function performSync() {
return; return;
} }
await augmentSettings(config);
// Check if sync not already in progress // Check if sync not already in progress
const ongoingSync: number | undefined = await store.get("sync.startTime"); const ongoingSync: number | undefined = await store.get("sync.startTime");
if (ongoingSync) { if (ongoingSync) {
@ -196,12 +199,22 @@ export async function performSync() {
} }
} }
async function augmentSettings(endpoint: SyncEndpoint) {
const syncSettings = await readSetting("sync", {});
if (syncSettings.excludePrefixes) {
endpoint.excludePrefixes = syncSettings.excludePrefixes;
}
}
export async function syncPage(page: string) { export async function syncPage(page: string) {
const config: SyncEndpoint = await store.get("sync.config"); const config: SyncEndpoint = await store.get("sync.config");
if (!config) { if (!config) {
// Sync not configured // Sync not configured
return; return;
} }
await augmentSettings(config);
// Check if sync not already in progress // Check if sync not already in progress
const ongoingSync: number | undefined = await store.get("sync.startTime"); const ongoingSync: number | undefined = await store.get("sync.startTime");
if (ongoingSync) { if (ongoingSync) {