1

I have a task need to be done every 4 hours or once a day.

In Java, it has quartz or spring or timer.

But in OCaml, how do I do that? Any good lib for that?

Jackson Tale
  • 25,428
  • 34
  • 149
  • 271

1 Answers1

6

I don't know any library to do that, but I think you can easily implement that kind of behavior using the Lwt library.

Little example, to print Hello world every 4 hours :

let rec hello () = 
    Lwt.bind (Lwt_unix.sleep 14400.) 
       (fun () -> print_endline "Hello, world !"; hello ())
Lwt.async (hello)

The Lwt.async function call the function given (here, hello) in an asynchronous light weight thread, so you're free to do other stuff in your program. As long as your program doesn't exit, "Hello world" will be printed every 4 hours.

If you want to be able to stop it, you can also launch the thread like this instead of Lwt.async :

let a = hello ()

And then, to stop the thread :

Lwt.cancel a

Be aware that Lwt.cancel throws a "Lwt.canceled" exception !

Then, to be able to launch a task at a particular time of day, I can only encourage you to use functions from the Unix module, like localtime and mktime.

ChristopheLec
  • 866
  • 5
  • 13
  • it will run forever? how to start/stop it? – Jackson Tale Jun 13 '13 at 16:28
  • 2
    This will run forever, it's not like cron: where your program isn't running. In this case your program is a daemon that sits in the background, in the case of cron, your program performs some work, and then dies off. – Kristopher Micinski Jun 13 '13 at 16:37
  • @KristopherMicinski if I want to stop the only way is kill my program? – Jackson Tale Jun 13 '13 at 16:39
  • no, I'm sure Lwt has a better way to handle it than this. If you want to run a daemon then this is a good solution. – Kristopher Micinski Jun 13 '13 at 16:44
  • @KristopherMicinski what if I want to run at a particular time everyday? instead of sleep for a time – Jackson Tale Jun 14 '13 at 06:03
  • 1
    @JacksonTale. You can either implement it the daemonized way (wait for a while, then check if the time has passed, etc...), or with cron. Personally I'd recommend writing an entry into the cron table for that scenario: the format is simple enough to figure out even if there aren't ocaml bindings. – Kristopher Micinski Jun 14 '13 at 11:44
  • I have written the code like you said `let rec start () = Lwt.bind (Lwt_unix.sleep 1.) (fun () -> print_endline "Hello, world !"; start ()) let _ = start ()`, but when I run it, it just quit, without any printing or sleeping. You said `as long as my program doesn't exit`. so how to keep the threading running behind even if my code doesn't have anything more to do? – Jackson Tale Jun 14 '13 at 13:43
  • 3
    Yes, you have to keep your program running or the light weight thread will die with the main thread. By doing "let _ = start ()", you are saying "okay, just launch a thread which will execute start, and do the next instruction", but there is no next instruction, so the program exits. You can tell your program to wait the end of start (which is never) by replacing `let _ = start ()` with `let _ = Lwt.bind (start ()) (Lwt.return)`. You can also just wait indefinitely using Lwt.wait : `Lwt.bind (fst (Lwt.wait ())) Lwt.return` – ChristopheLec Jun 14 '13 at 14:05
  • thank you. I also begin to try to really understand lwt by reading its manual. Any other good tutorial or manual ? – Jackson Tale Jun 14 '13 at 14:08
  • As far as I know, there is only the manual for now unfortunately. – ChristopheLec Jun 14 '13 at 14:12
  • Can I do `Lwt_main.run (start())` for the purpose above? – Jackson Tale Jun 14 '13 at 14:37
  • 1
    Yes, and it seems more appropriate than my version with Lwt.bind. – ChristopheLec Jun 14 '13 at 14:52
  • sorry to bother you again. for a task at a particular time, you said you should use `Unix`. So what I should do is that sleep for 10 secs and then check whether the current time is the desired time, if it is then I do the dirty work; if not, continue to sleep 10 secs and check again, so on so forth? – Jackson Tale Jun 15 '13 at 12:32
  • I recommend [my lecture on monads](http://www.ii.uni.wroc.pl/~lukstafi/pmwiki/uploads/Functional/functional-lecture08.pdf) (the [course](http://www.ii.uni.wroc.pl/~lukstafi/pmwiki/index.php?n=Functional.Functional)) and [Jerome Vouillon “Lwt: a Cooperative Thread Library”](http://www.pps.univ-paris-diderot.fr/~vouillon/publi/lwt.pdf). – lukstafi Jun 15 '13 at 20:29
  • Yes, that is what I meant. However, there might be other solutions, like calculating the required sleeping time using mktime and localtime. – ChristopheLec Jun 17 '13 at 09:56