Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

irmin-pack: remove append-only external flush callback #2235

Merged
merged 7 commits into from
Aug 1, 2023

Conversation

art-w
Copy link
Contributor

@art-w art-w commented Apr 7, 2023

I was trying to simplify the logic to update the control file in the file manager. The Append_only_file was using an external callback to signify the need to flush when its buffer was full, which would in turn update the control file (to make that portion of the file visible)... but then we could end up with a visible partially written commit, which isn't an issue in itself, but isn't how we think about the control file payload. As the flush threshold was fairly high, I don't think this "partial flush" was really stress tested either (?)

Anyway it's gone, as it should be fine to just write to the append-only files when their memory buffer is full, we only need to update the control file at the end to publish the writes.

While testing I discovered that I broke the Dict flushing its end_poff to the control file, so I refactored that a bit to match with the chunks/sparse file abstractions (inverting the File_manager dependency). A few breaking changes here:

  • Previously the dict updates would become visible "in the middle" of the store flushing, now it's at the same time as the rest (... this should be fine since dict updates are only useful to interpret that rest)
  • Removed the dict consumers callback, as it looked unused (?)

Copy link
Member

@metanivek metanivek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This drastically simplifies/clarifies the code. Thanks!

Depending on the benchmark results, we may need to come up with some ideas for the flush threshold.

CHANGES.md Outdated Show resolved Hide resolved
src/irmin-pack/unix/file_manager.ml Show resolved Hide resolved
src/irmin-pack/unix/file_manager.ml Show resolved Hide resolved
Comment on lines +160 to +162
let* () = flush_suffix t in
let+ () = flush_control t in
List.iter (fun { after_flush } -> after_flush ()) t.suffix_consumers
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous code skipped writing the control file and running after_flush if the suffix was empty. I like the straightforward nature of your refactor, so I don't think we should necessarily maintain previous behavior (and I don't think it matters in practice). I mostly wanted to point it out in case you have thoughts about it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks :) I hope the control file rewrite is avoided by line 149 above! (if new_pl = pl then Ok ())
I believe the only suffix consumer is used to clear the staging table in Pack_store so it should have little impact... and I don't think this staging reset should be setup like that anyway, it's a bit obfuscated :P

@@ -21,23 +21,19 @@ module Make (Io : Io.S) (Errs : Io_errors.S with module Io = Io) = struct
module Io = Io
module Errs = Errs

let auto_flush_threshold = 16_384
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm running a benchmark to see what impact this has.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ran a benchmark that was slower but then I remembered that 3.8 changed LRU semantics. I need to re-run with an adjusted LRU size.

Copy link
Member

@metanivek metanivek Jul 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran the benchmark with adjusted LRU entry size. https://github.com/metanivek/irmin-tezos-benchmarking/tree/rm_auto_flush/benchmarks/2023-07-pr-2235

I'm having issues with generating stats.txt for the benchmark (separate issue) but here are the results.

The first comparison is against 3.7.1 baseline that we've been using.
stats

This makes this PR look like it is a huge performance improvement. Well, then I remembered that the new LRU performs better when compared to 3.7.

So here is this PR compared to the equivalent run for the new LRU (15k entries).
stats new_lru

I don't know the exact numbers since I can't get the summary data yet, but I can't imagine it is much different, given how closely these lines are. I think this PR is good to go from a performance perspective!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a ton for running the benchmarks! It's great to have confirmation that this PR doesn't have any impact as expected :)

@codecov-commenter
Copy link

Codecov Report

Merging #2235 (04e1790) into main (e6cb805) will decrease coverage by 0.01%.
The diff coverage is 93.24%.

❗ Current head 04e1790 differs from pull request most recent head 02fd19f. Consider uploading reports for the commit 02fd19f to get more accurate results

❗ Your organization is not using the GitHub App Integration. As a result you may experience degraded service beginning May 15th. Please install the Github App Integration for your organization. Read more.

@@            Coverage Diff             @@
##             main    #2235      +/-   ##
==========================================
- Coverage   68.17%   68.17%   -0.01%     
==========================================
  Files         138      138              
  Lines       16739    16733       -6     
==========================================
- Hits        11412    11407       -5     
+ Misses       5327     5326       -1     
Files Changed Coverage Δ
src/irmin-pack/unix/gc_worker.ml 3.75% <0.00%> (ø)
src/irmin-pack/unix/pack_store.ml 78.84% <ø> (ø)
src/irmin-pack/unix/store.ml 65.55% <ø> (-0.23%) ⬇️
src/irmin-pack/unix/file_manager.ml 86.93% <91.17%> (+1.15%) ⬆️
src/irmin-pack/unix/append_only_file.ml 87.30% <93.75%> (+2.30%) ⬆️
src/irmin-pack/conf.ml 86.79% <100.00%> (-1.74%) ⬇️
src/irmin-pack/unix/chunked_suffix.ml 85.96% <100.00%> (-0.13%) ⬇️
src/irmin-pack/unix/dict.ml 95.65% <100.00%> (+1.20%) ⬆️
src/irmin-pack/unix/sparse_file.ml 84.49% <100.00%> (ø)

... and 3 files with indirect coverage changes

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@metanivek metanivek merged commit 0ca20cc into mirage:main Aug 1, 2023
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants