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

Remove lwt from low level finalise #2064

Closed
wants to merge 2 commits into from

Conversation

icristescu
Copy link
Contributor

Part of #2039 is to remove lwt from low level start (already done) and finalise (this PR).

Rebased on #2063.

@icristescu icristescu added the no-changelog-needed No changelog is needed here label Aug 31, 2022
@@ -108,10 +108,10 @@ module Unix = struct
let await t =
match t.status with
| `Running ->
let+ pid, status = Lwt_unix.waitpid [] t.pid in
let pid, status = Unix.waitpid [] t.pid in
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm a bit concerned about this change - Lwt_unix.waitpid blocked the current promise, but allowed for other Lwt promises to run. I think with this change we are blocking all promises in this thread?

Copy link
Member

Choose a reason for hiding this comment

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

Hmm, this is a good question. We do not use Lwt for other I/O operations (like in io.ml) so I'm wondering if this change makes anything that much worse. In the high-level gc api (that is used by Tezos), await will never be called -- we only check status. Does that change anything for you?

Copy link
Member

Choose a reason for hiding this comment

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

I agree we should avoid doing this as it is blocking the whole process that defeat the purpose of that API

Copy link
Member

Choose a reason for hiding this comment

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

@samoht this function is not called as a part of the high-level api. It only calls status, which is already using Unix.waitpid [ Unix.WNOHANG ] t.pid.

@codecov-commenter
Copy link

Codecov Report

Merging #2064 (8b1cb40) into main (5374885) will decrease coverage by 0.01%.
The diff coverage is 42.04%.

❗ Current head 8b1cb40 differs from pull request most recent head 1f59acd. Consider uploading reports for the commit 1f59acd to get more accurate results

@@            Coverage Diff             @@
##             main    #2064      +/-   ##
==========================================
- Coverage   64.34%   64.33%   -0.02%     
==========================================
  Files         131      133       +2     
  Lines       15584    15571      -13     
==========================================
- Hits        10028    10017      -11     
+ Misses       5556     5554       -2     
Impacted Files Coverage Δ
src/irmin-pack/unix/gc_worker.ml 8.59% <8.59%> (ø)
src/irmin-pack/unix/async.ml 53.06% <40.00%> (-0.94%) ⬇️
src/irmin-pack/unix/ext.ml 61.15% <70.00%> (-5.51%) ⬇️
src/irmin-pack/unix/gc.ml 75.72% <75.25%> (+67.13%) ⬆️
src/irmin-pack/unix/file_manager.ml 83.90% <100.00%> (+1.23%) ⬆️
src/irmin-pack/unix/gc_intf.ml 100.00% <100.00%> (ø)
src/irmin-test/store.ml 94.82% <0.00%> (-0.06%) ⬇️

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

@Ngoguey42
Copy link
Contributor

I now remember how we planned on shipping the GC without Lwt. The idea was to check for GC-worker termination using a non-blocking call to waitpid.

Removing lwt from low level finalise would mean bringing back that technique.

@metanivek
Copy link
Member

@Ngoguey42 we already do not use Lwt for checking status of the gc worker process, so I think this is already done. See #2064 (comment)

Comment on lines 273 to 625
if wait then
let* status = Async.await t.task in
let status = Async.await t.task in
go status
else
match Async.status t.task with
| `Running -> Lwt.return_ok `Running
| `Running -> Ok `Running
| status -> go status)
Copy link
Contributor

Choose a reason for hiding this comment

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

A solution to the waitpid/lwt problem would be to turn the existing finalise into finalise_nowait:

val finalise : wait:bool -> t -> ([> 'Running | 'Finalised of stats ], Args.Errs.t) result Lwt.t
val finalise_nowait :       t -> ([> 'Running | 'Finalised of stats ], Args.Errs.t) result

and then add a new finalise_wait function that uses lwt:

val finalise : wait:bool -> t -> ([> 'Running | 'Finalised of stats ], Args.Errs.t) result Lwt.t
val finalise_wait :         t -> ([> 'Running | 'Finalised of stats ], Args.Errs.t) result Lwt.t

This way, lwt would be gone from all but one function of that part of the code

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think this would lead to some code duplication, I'm not sure its worth: its not removing lwt from async and finalise is already the only place in the gc where we return lwt.

I'm closing this for now. If you disagree, please open this again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
no-changelog-needed No changelog is needed here
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants