╭ changed ───────╮ │src/progress.zig│ ╰────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────────────────────────────────────────────────────────────────────────────╮ │20 sess: ?*ssh.SessionCtx = null, │ │21 // set once it has hung up, so the phase in flight can stop too │ │22 gone: bool = false, │ │23 + // a pushed repo's db and the size it may grow to │ │24 + size_limit: ?SizeLimit = null, │ │25 + // set once the db outgrew size_limit, so the phase in flight can stop too│ │26 + too_large: bool = false, │ │27 label: []const u8 = "Processing commits", │ │28 count: usize = 0, │ │29 total: usize = 0, │ ╰──────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────╮ │32 │ │33 // how many items a phase with no total advances between reports │ │34 const report_every = 1000; │ │35 + │ │36 + pub const SizeLimit = struct { │ │37 + file: std.Io.File, │ │38 + max: u64, │ │39 + }; │ │40 + │ │41 + // fail once the pushed repo's db has outgrown its limit │ │42 + pub fn checkSize(self: *Sideband, io: std.Io) !void { │ │43 + const limit = self.size_limit orelse return; │ │44 + if (try limit.file.length(io) <= limit.max) return; │ │45 + self.too_large = true; │ │46 + return error.RepoTooLarge; │ │47 + } │ │48 │ │49 // the phases a client is told about, listed so a new kind has to be │ │50 // decided on rather than inherit whatever label was last set. unpacking is│ ╰───────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────╮ │57 }; │ │58 } │ │59 │ │43 - pub fn run(self: *Sideband, _: std.Io, event: rp.ProgressEvent) !void { │ │60 + pub fn run(self: *Sideband, io: std.Io, event: rp.ProgressEvent) !void { │ │61 + // every unpacked object reports, so a push stops soon after crossing the limit│ │62 + if (event == .complete_one) try self.checkSize(io); │ │63 switch (event) { │ │64 .start => |start| { │ │65 if (!reported(start.kind)) return; │ ╰───────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │124 } │ │125 }; │ │126 │ │108 -// whether the client the work is reporting to has hung up. only a sideband │ │109 -// reporter probes, so any other context never cancels. │ │127 +// whether the client the work is reporting to has hung up, or its push has │ │128 +// outgrown the repo size limit. only a sideband reporter probes, so any other │ │129 +// context never cancels. │ │130 pub fn cancelled(comptime repo_opts: rp.RepoOpts(.xit), progress_ctx_maybe: ?repo_opts.ProgressCtx) bool {│ │131 if (repo_opts.ProgressCtx != *Sideband) return false; │ │132 const progress_ctx = progress_ctx_maybe orelse return false; │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────╮ │113 - return progress_ctx.gone; │ │133 + return progress_ctx.gone or progress_ctx.too_large;│ │134 } │ │135 │ ╰────────────────────────────────────────────────────────────╯