╭ changed ────╮ │src/event.zig│ ╰─────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │144 │ │145 // open the db in `repo_dir`, creating it if it doesn't exist │ │146 pub fn create(io: std.Io, allocator: std.mem.Allocator, repo_dir: std.Io.Dir) !Self { │ │147 - const file = try repo_dir.createFile(io, db_name, .{ .truncate = false, .read = true }); │ │147 + const file = try repo_dir.createFile(io, db_name, .{ .truncate = false, .read = true, .lock = .exclusive });│ │148 return fromFile(io, allocator, file); │ │149 } │ │150 │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │151 - // open the db in `repo_dir`, or null if it doesn't exist │ │151 + // open the db in `repo_dir` for reading, or null if it doesn't exist │ │152 pub fn open(io: std.Io, allocator: std.mem.Allocator, repo_dir: std.Io.Dir) !?Self { │ │153 - const file = repo_dir.openFile(io, db_name, .{ .mode = .read_write, .lock = .none }) catch |err| switch (err) { │ │153 + const file = repo_dir.openFile(io, db_name, .{ .mode = .read_write, .lock = .shared }) catch |err| switch (err) {│ │154 error.FileNotFound => return null, │ │155 else => |e| return e, │ │156 }; │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────╮ │157 return try fromFile(io, allocator, file); │ │158 } │ │159 │ │160 + // remove the db from `repo_dir`, so a repo whose events branch │ │161 + // disappeared doesn't keep showing stale issues │ │162 + pub fn delete(io: std.Io, repo_dir: std.Io.Dir) !void { │ │163 + repo_dir.deleteFile(io, db_name) catch |err| switch (err) { │ │164 + error.FileNotFound => {}, │ │165 + else => |e| return e, │ │166 + }; │ │167 + } │ │168 + │ │169 fn fromFile(io: std.Io, allocator: std.mem.Allocator, file: std.Io.File) !Self {│ │170 errdefer file.close(io); │ │171 │ ╰─────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────╮ │188 allocator.destroy(self.db); │ │189 } │ │190 │ │182 - // consume the events on `repo`'s `ref` into this db │ │191 + // consume the events on `repo`'s `ref` into this db. the db must come│ │192 + // from `create`, whose handle holds the exclusive lock guarding the │ │193 + // transaction. │ │194 pub fn consume( │ │195 self: *Self, │ │196 comptime repo_kind: rp.RepoKind, │ ╰───────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │217 try consumeInTransaction(repo_kind, repo_opts, read_state, ctx.db, &moment, ctx.io, ctx.allocator, ctx.ref);│ │218 } │ │219 }; │ │209 - │ │210 - try self.file.lock(io, .exclusive); │ │211 - defer self.file.unlock(io); │ │220 │ │221 const history = try DB.ArrayList(.read_write).init(self.db.rootCursor()); │ │222 try history.appendContext(.{ .slot = try history.getSlot(-1) }, Ctx{ │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │247 const remote_ref: rf.Ref = .{ .kind = .{ .remote = remote_name }, .name = events_ref.name };│ │248 if (try repo.readRef(io, remote_ref)) |oid| break :blk .{ remote_ref, oid }; │ │249 } │ │250 + // the branch is gone (or never existed): drop any db from a previous │ │251 + // sync rather than serving its issues indefinitely │ │252 + try LocalEventDB(repo_opts.hash).delete(io, repo.core.repo_dir); │ │253 return; │ │254 }; │ │255 │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯