diff --git a/bin/dune b/bin/dune index d7dfc94..a9afd5f 100644 --- a/bin/dune +++ b/bin/dune @@ -2,4 +2,4 @@ (public_name ocaml-systemd) (name main) (modes byte exe) - (libraries systemd systemd.xlog eio_main fmt xlog)) + (libraries systemd systemd.xlog systemd.main eio_main fmt xlog)) diff --git a/bin/main.ml b/bin/main.ml index 2e87c1b..2db1471 100644 --- a/bin/main.ml +++ b/bin/main.ml @@ -2,23 +2,16 @@ include (val Xlog.logs __FUNCTION__) open Eio.Std -let () = Eio_main.run @@ fun env -> +let () = Systemd_main.run ~min_level:Xlog.DEBUG ~ready_status:(Some "meow meow") ~shutdown:(fun env _ctx -> Eio.Time.sleep env#clock 10.0) @@ fun env notify -> let clock = Eio.Stdenv.clock env in - Switch.run ~name:"main" @@ fun sw -> - if Systemd.is_journald_attached () then - Xlog.add_writer (Systemd_xlog.make_writer ~sw ~env) ~min_level:Xlog.DEBUG - else - Xlog.init_pretty_writer stdout ~min_level:Xlog.DEBUG; - + Switch.run @@ fun sw -> info (fun m -> m "meow meow meow"); let fds = Systemd.Fdstore.listen_fds ~sw in List.iter (fun (name, fd) -> Stdlib.Format.printf "got fd %a=%a\n%!" (Fmt.option ~none:(Fmt.any "") Fmt.string) name Eio_unix.Fd.pp fd; Eio_linux.Low_level.writev fd [Cstruct.of_string "meow"]) fds; - let ctx = Systemd.Notify.make ~sw ~env in - info (fun m -> m "notifying!"); - Systemd.Notify.ready ctx; info (fun m -> m "performing barrier"); - Systemd.Notify.barrier ctx; + Systemd.Notify.barrier notify; info (fun m -> m "done"); - Eio.Time.sleep clock 2.0 + Eio.Time.sleep clock 10.0; + info (fun m -> m "done 2") diff --git a/lib_main/dune b/lib_main/dune new file mode 100644 index 0000000..dfbec41 --- /dev/null +++ b/lib_main/dune @@ -0,0 +1,5 @@ +(library + (name systemd_main) + (public_name systemd.main) + (preprocess (pps ppx_unicode)) + (libraries eio eio_linux systemd systemd.xlog xlog)) diff --git a/lib_main/systemd_main.ml b/lib_main/systemd_main.ml new file mode 100644 index 0000000..bfd4a28 --- /dev/null +++ b/lib_main/systemd_main.ml @@ -0,0 +1,45 @@ +let noop _env _ctx = () + +let run ?(min_level=Xlog.WARN) ?(init=noop) ?(ready_status=None) ?(reload=noop) ?(shutdown=noop) func = + Eio_linux.run @@ fun env -> + Eio.Switch.run ~name:"main" @@ fun sw -> + if Systemd.is_journald_attached () then + Xlog.add_writer (Systemd_xlog.make_writer ~sw ~env) ~min_level + else + Xlog.init_pretty_writer stdout ~min_level; + + let ctx = Systemd.Notify.make ~sw ~env in + + let stop_cond = Eio.Condition.create () in + let reload_cond = Eio.Condition.create () in + + let handle_stop _ = + Eio.Condition.broadcast stop_cond + in + let handle_reload _ = + Eio.Condition.broadcast reload_cond + in + Sys.set_signal Sys.sigint (Signal_handle handle_stop); + Sys.set_signal Sys.sigterm (Signal_handle handle_stop); + Sys.set_signal Sys.sighup (Signal_handle handle_reload); + + init env ctx; + + let rec reload_loop () = + Eio.Condition.await_no_mutex reload_cond; + Systemd.Notify.reloading ctx; + reload env ctx; + Systemd.Notify.ready ~status:ready_status ctx; + reload_loop () + in + + Eio.Switch.on_release sw (fun () -> + Systemd.Notify.stopping ctx; + shutdown env ctx); + + Systemd.Notify.ready ~status:ready_status ctx; + + Eio.Fiber.any + [(fun () -> Eio.Condition.await_no_mutex stop_cond); + reload_loop; + (fun () -> func env ctx)];