Running Lwt.t code in a data structure?

I have some OCaml code that was being loaded by Ocisgen. Some of that code created expressions of type “Yojson.Safe.json Lwt.t” and stored them in a data structure. An endpoint I created for Ocsigen allowed me to examine those values periodically, that is, checking their state. Eventually, those expressions evolved to the “Return” state, and I could pull out a JSON value.

For various reasons, I want to run the same code with a different Web server, so that the code is called via SCGI. In this case, the expressions remain perpetually in a “Sleep” state. It seems that Ocsigen runs code in the Lwt monad for me, but that’s not true when using the other Web server. I could call “Lwt_main.run” on the expression before storing it in the data structure, but that would introduce synchronization, but then I lose the concurrency benefits of Lwt.

Is there a way to get these expressions to run “in the background” in what is otherwise non-Lwt-monadic code?

1 Like

I had a similar problem and I used Lwt.on_success.
It works in my case.

There is also Lwt.async

@Paul_A_Steckler, if @Juloo’s suggestion doesn’t help, could you give more detail on the expressions you are referring to?

If evaluation of the expressions depends on something that only Ocsigen runs, then you will need to call into Ocsigen somehow, so it can do whatever I/O it does to evaluate that expression.

If this is only a matter of calling Lwt_main.run on something, you should call it on one “outer” promise at the top level of your program. This will resolve your Yojson.Safe.json Lwt.t at the same time it resolves any other Lwt promise.

Is the rest of your SCGI app written using Lwt, doing blocking I/O, or doing something else?

The app is using the OCamlNet library, which does not use Lwt at all. It’s a mismatch for what I’m doing.

I found another OCaml library for SCGI, which does use Lwt. I think it will handle my use case.

@Juloo, thanks for mentioning Lwt.on_success. That should help structure my code a little better.

1 Like

@Paul_A_Steckler Indeed, Lwt (or any other asynchronous I/O library) is usually an all-or-nothing choice. If you want to use it, most of your I/O libraries will have to use it as well.

In some cases, though, you can get away with using a local Lwt_main.run, if the rest of your code is using blocking I/O anyway.

Glad you found the other library.