MCPcopy Create free account
hub / github.com/cloudflare/computer / pushOnce

Function pushOnce

packages/rpc/src/sync-driver.ts:292–364  ·  view source on GitHub ↗
(db: Database, remote: SyncRPC, backend?: string)

Source from the content-addressed store, hash-verified

290// successful push. The wire shape mirrors pullOnce in reverse:
291// stage bytes the remote lacks, then push the entry stream.
292export async function pushOnce(db: Database, remote: SyncRPC, backend?: string): Promise<number> {
293 const sincePush = readWatermark(db, "pushRev", backend);
294 const localRev = currentRev(db);
295 if (localRev <= sincePush) return 0;
296
297 const entries: ChangeEntry[] = [];
298 const wantedHashes: Uint8Array[] = [];
299 const seenHash = new Set<string>();
300 for await (const e of coalesceChanges(db, { rev: sincePush, path: null })) {
301 entries.push(e);
302 if (e.kind === "file") {
303 for (const c of e.chunks) {
304 const k = hex(c.hash);
305 if (!seenHash.has(k)) {
306 seenHash.add(k);
307 wantedHashes.push(c.hash);
308 }
309 }
310 }
311 }
312 if (entries.length === 0) return 0;
313
314 // Probe the remote for the chunks it already holds; ship the
315 // complement.
316 const remoteHas = new Set<string>();
317 if (wantedHashes.length > 0) {
318 const have = await remote.hasObjects(wantedHashes);
319 for (const h of have) remoteHas.add(hex(h));
320 }
321 const missing = wantedHashes.filter((h) => !remoteHas.has(hex(h)));
322
323 if (missing.length > 0) {
324 const local = (function* () {
325 for (const h of missing) {
326 const row = db.one<{ bytes: Uint8Array }>(
327 "SELECT bytes FROM vfs_blob_bytes WHERE hash = ?",
328 h,
329 );
330 if (row === undefined) {
331 throw new Error(`pushOnce: missing local blob ${hex(h)}`);
332 }
333 yield { hash: h, bytes: row.bytes };
334 }
335 })();
336 const bytesStream = new ReadableStream<{ hash: Uint8Array; bytes: Uint8Array }>({
337 pull(controller) {
338 const next = local.next();
339 if (next.done) controller.close();
340 else controller.enqueue(next.value);
341 },
342 });
343 await remote.pushObjects(bytesStream);
344 }
345
346 const entryStream = new ReadableStream<ChangeEntry>({
347 start(controller) {
348 for (const e of entries) controller.enqueue(e);
349 controller.close();

Callers 5

pushMethod · 0.90
computerd.test.tsFile · 0.85
tickFunction · 0.85

Calls 12

readWatermarkFunction · 0.90
currentRevFunction · 0.90
coalesceChangesFunction · 0.90
assertAppliedPushCursorFunction · 0.90
writeWatermarkFunction · 0.90
hasMethod · 0.80
oneMethod · 0.80
hexFunction · 0.70
pushMethod · 0.65
addMethod · 0.65
hasObjectsMethod · 0.65
pushObjectsMethod · 0.65

Tested by

no test coverage detected