ocamlocsigenocaml-lwt

How to make something lwt supported?


I am trying to understand the term lwt supported.


So assume I have a piece of code which connect a database and write some data: Db.write conn data. It has nothing to do with lwt yet and each write will cost 10 sec.

Now, I would like to use lwt. Can I directly code like below?

let write_all data_list = Lwt_list.iter (Db.write conn) data_list
let _ = Lwt_main.run(write_all my_data_list)

Support there are 5 data items in my_data_list, will all 5 data items be written into the database sequentially or in parallel?


Also in Lwt manually or http://ocsigen.org/tutorial/application, they say

Using Lwt is very easy and does not cause troubles, provided you never use blocking functions (non cooperative functions). Blocking functions can cause the entre server to hang!

I quite don't understand how to not using blocking functions. For every my own function, can I just use Lwt.return to make it lwt support?


Solution

  • Yes, your code is correct. The principle of lwt supported is that everything that can potentially take time in your code should return an Lwt value.

    About Lwt_list.iter, you can choose whether you want the treatment to be parallel or sequential, by choosing between iter_p and iter_s :

    In iter_s f l, iter_s will call f on each elements of l, waiting for completion between each element. On the contrary, in iter_p f l, iter_p will call f on all elements of l, then wait for all the threads to terminate.

    About the non-blocking functions, the principle of the Light Weight Threads is that they keep running until they reach a "cooperation point", i.e. a point where the thread can be safely interrupted or has nothing to do, like in a sleep.

    But you have to declare you enter a "cooperation point" before actually doing the sleep. This is why the whole Unix library has been wrapped, so that when you want to do an operation that takes time (e.g. a write), a cooperation point is automatically reached.

    For your own function, if you use IOs operations from Unix, you should instead use the Lwt version (Lwt_unix.sleep instead of Unix.sleep)