I am trying to use the OBus library with Lwt_react . It uses "functional reactive programming" for properties and signals.
The problem (as stated in the React documentation ) is that OCaml can remove your callback while you use it. There is a keep function that holds the handler forever, but I do not want this. In the end, I want to free him, just not while I still need him.
So, I thought I would bind a handler to a switch:
let keep ~switch handler = Lwt_switch.add_hook (Some switch) (fun () -> ignore handler; Lwt.return () )
But my event handler still collects garbage (which makes sense, since the code to turn off the switch is called when a signal arrives, so it is only a signal handler, keeping the switch alive first).
Here is a simplified (separate) version of my code:
(* ocamlfind ocamlopt -package react,lwt,lwt.react,lwt.unix -linkpkg -o test test.ml *) let finished_event, fire_finished = React.E.create () let setup () = let switch = Lwt_switch.create () in let finished, waker = Lwt.wait () in let handler () = Lwt.wakeup waker () in let dont_gc_me = Lwt_react.E.map handler finished_event in ignore dont_gc_me; (* What goes here? *) print_endline "Waiting for signal..."; Lwt.bind finished (fun () -> Lwt_switch.turn_off switch) let () = let finished = Lwt.protected (setup ()) in Gc.full_major (); (* Force GC, to demonstrate problem *) fire_finished (); (* Simulate send *) Lwt_main.run finished; print_endline "Done";
Without the Gc.full_major line Gc.full_major this usually prints Done . However, it just freezes when Waiting for signal...
Edit: I split setup (real code) from the test driver and added the Lwt.protected wrapper to avoid masking the problem by accident with canceling Lwt.
garbage-collection reactive-programming ocaml ocaml-lwt
Thomas leonard
source share