Conversation
| try | ||
| match Flow.read ch (Cstruct.sub buf 0 max_chunk_size) with | ||
| | 0 -> Promise.resolve set_th (Ok ()) | ||
| | n -> dst (Cstruct.to_string buf ~off:0 ~len:n); aux () | ||
| with End_of_file -> Promise.resolve set_th (Ok ()) |
There was a problem hiding this comment.
| try | |
| match Flow.read ch (Cstruct.sub buf 0 max_chunk_size) with | |
| | 0 -> Promise.resolve set_th (Ok ()) | |
| | n -> dst (Cstruct.to_string buf ~off:0 ~len:n); aux () | |
| with End_of_file -> Promise.resolve set_th (Ok ()) | |
| match Flow.read ch (Cstruct.sub buf 0 max_chunk_size) with | |
| | 0 -> Promise.resolve set_th (Ok ()) | |
| | n -> dst (Cstruct.to_string buf ~off:0 ~len:n); aux () | |
| | exception End_of_file -> Promise.resolve set_th (Ok ()) |
talex5
left a comment
There was a problem hiding this comment.
Thanks for experimenting with this! I skimmed it and added a few comments.
The trickiest part at the moment seems to be how to handle cancellation correctly. I was thinking of maybe just having a global switch that's passes in via Build.build that everything uses to spawn fibers etc. and that can be the switch that is cancelled if the user does -- any thoughts on this @talex5 ?
Ideally, we just remove almost everything to do with cancellation. If the user wants to cancel a build they can just cancel the fiber running it and let Eio's cancellation system sort it out.
lib/btrfs_store.ml
Outdated
| let purge path = | ||
| Sys.readdir path |> Array.to_list |> Lwt_list.iter_s (fun item -> | ||
| let purge t path = | ||
| Sys.readdir path |> Array.to_list |> Fiber.iter (fun item -> |
There was a problem hiding this comment.
Note: the direct translation of Lwt_list.iter_s is List.iter.
| (libraries lwt lwt.unix fmt fmt.cli fmt.tty tar-unix obuilder cmdliner logs.fmt logs.cli)) | ||
| (libraries eio_main fmt fmt.cli fmt.tty tar-unix obuilder cmdliner logs.fmt logs.cli)) | ||
|
|
||
| (vendored_dirs lwt_eio.0.2 eioio tar.2.0.1) |
There was a problem hiding this comment.
It's called eio now. You might want to rename your fork.
lib/btrfs_store.ml
Outdated
| let args = if sudo && not running_as_root then "sudo" :: args else args in | ||
| Os.exec ~stdout:`Dev_null args | ||
| Switch.run @@ fun sw -> | ||
| Os.exec ~sw ~process:t.process args |
There was a problem hiding this comment.
Os.exec shouldn't take a switch, because when it returns the process has already finished.
lib/btrfs_store.ml
Outdated
| let check_kernel_version () = | ||
| Os.pread ["uname"; "-r"] >>= fun kver -> | ||
| let check_kernel_version process = | ||
| let kver = Switch.run @@ fun sw -> Os.pread ~sw ~process ["uname"; "-r"] in |
There was a problem hiding this comment.
Shouldn't have a switch here either.
lib/build.ml
Outdated
| ) | ||
| >>= fun mounts -> | ||
| let mounts = | ||
| Fiber.map (fun { Obuilder_spec.Cache.id; target; buildkit_options = _ } -> |
There was a problem hiding this comment.
For a direct translation:
| Fiber.map (fun { Obuilder_spec.Cache.id; target; buildkit_options = _ } -> | |
| List.map (fun { Obuilder_spec.Cache.id; target; buildkit_options = _ } -> |
lib/build_log.mli
Outdated
| (** [empty] is a read-only log with no content. *) | ||
|
|
||
| val of_saved : string -> t Lwt.t | ||
| val of_saved : Eio.Dir.t -> string -> t |
There was a problem hiding this comment.
| val of_saved : Eio.Dir.t -> string -> t | |
| val of_saved : Eio.Path.t -> t |
| log : Build_log.t Lwt.t; | ||
| result : (([`Loaded | `Saved] * S.id), [`Cancelled | `Msg of string]) Lwt_result.t; | ||
| set_cancelled : unit Promise.u; (* Resolve this to cancel (when [users = 0]). *) | ||
| log : (Build_log.t, exn) result Promise.t; |
There was a problem hiding this comment.
| log : (Build_log.t, exn) result Promise.t; | |
| log : Build_log.t Promise.or_exn; |
lib/os.ml
Outdated
| let r, w = Lwt_unix.pipe_in ~cloexec:true () in | ||
| let w = { raw = w; needs_close = true } in | ||
| Lwt.finalize | ||
| let with_pipe_from_child ~sw fn = |
There was a problem hiding this comment.
| let with_pipe_from_child ~sw fn = | |
| let with_pipe_from_child fn = | |
| Switch.run @@ fun sw -> |
lib/s.ml
Outdated
| val run : | ||
| cancelled:unit Lwt.t -> | ||
| ?stdin:Os.unix_fd -> | ||
| sw:Eio__core.Switch.t -> |
There was a problem hiding this comment.
Shouldn't need a switch here. Everything will be finished when run returns.
| sw:Eio__core.Switch.t -> | ||
| dir:#Eio.Dir.t -> | ||
| process:Eio.Process.t -> | ||
| cancelled:unit Eio.Promise.t -> |
There was a problem hiding this comment.
Can probably remove this and use Eio's built-in cancellation.
|
Are there any blockers apart from applying the suggestions from the code review and rebasing? I'd definitely enjoy debugging with backtraces (hoping that the switch to OCaml 5 and Eio would provide them). |
However, you might not enjoy that it will no longer work on Windows :-( See ocaml-multicore/eio#125 for remaining issues if you want to help! |
89e84ac to
ccd3f2f
Compare
This is a very experimental PR/branch that starts trying to port OBuilder to Eio. As part of some other work I wanted to start tackling ocaml-multicore/eio#126 so I was looking for a good candidate that made heavy use of subprocesses and redirections!
This branch is currently building with this branch of Eio: https://github.com/patricoferris/eioio/tree/processes
The trickiest part at the moment seems to be how to handle cancellation correctly. I was thinking of maybe just having a global switch that's passes in via
Build.buildthat everything uses to spawn fibers etc. and that can be the switch that is cancelled if the user does -- any thoughts on this @talex5 ?