Skip to content

Commit 189e64c

Browse files
authored
Merge pull request mouredev#2787 from luishendrix92/main
#15 - OCaml
2 parents 4ddd48f + a4cb46e commit 189e64c

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
open Lwt_io
2+
3+
(*****************************************************************************)
4+
(* *)
5+
(* Asynchronous Programming (and Concurrency) *)
6+
(* *)
7+
(* Concurrency in OCaml is done via Threads, and it can also leverage the *)
8+
(* [Domain] data structure for parallel programming. However there are 2 *)
9+
(* main libraries to handle and wrap async operations: Lwt (acronym for *)
10+
(* "lightweight threads") and Async. *)
11+
(* *)
12+
(* Lwt is a promise-like library that wraps IO and Unix operations, among *)
13+
(* other tasks that may need to be done concurrently. Many libraries are *)
14+
(* built with or on top of it; [cohttp] (HTTP library) is an example. *)
15+
(* A new library is on development called Riot which promises Erlang *)
16+
(* -like actor concurrency that can be run on multiple cores. But for this *)
17+
(* exercise I'm gonna use 3 {e opam} packages: *)
18+
(* *)
19+
(* 1. [lwt]: The main Lwt package that contains many modules. One of them *)
20+
(* is the [Lwt_io] module that wraps your usual IO operations (print, *)
21+
(* read_char, read_line, assert, etc). And the core [Lwt] module that *)
22+
(* contains the glue functions like [join], [return], [pick], [bind]. *)
23+
(* 2. [lwt.unix]: Unix functions wrapped by promises, like [sleep]. *)
24+
(* 3. [lwt_ppx]: Syntax sugar for [bind] (and other) operations. Example: *)
25+
(* [let%lwt ln = Lwt_io.read_line () in printf "I got: %s" ln] instead *)
26+
(* of [Lwt_io.read_line () >>= fun ln -> Lwt_io.printf "I got %s" ln]. *)
27+
(* *)
28+
(*****************************************************************************)
29+
30+
let time_now () =
31+
let open Core.Time_float in
32+
now () |> to_ofday ~zone:Zone.utc |> Ofday.to_sec_string
33+
;;
34+
35+
let delay_function ?(seconds = 1.0) ~name f =
36+
let%lwt () =
37+
printf "[%s] will run after %.2f seconds | %s\n" name seconds (time_now ())
38+
in
39+
let%lwt () = Lwt_unix.sleep seconds in
40+
f ();
41+
printf "[%s] has been called | %s\n" name (time_now ())
42+
;;
43+
44+
(* Output:
45+
46+
[Ejercicio] will run after 4.00 seconds | 21:22:36
47+
The answer is 42!
48+
[Ejercicio] has been called | 21:22:40
49+
*)
50+
let _ =
51+
Lwt_main.run
52+
@@ delay_function ~name:"Ejercicio" ~seconds:4.0 (fun () ->
53+
print_endline "The answer is 42!")
54+
;;
55+
56+
(****************************************************************************)
57+
(* *)
58+
(* Dificultad Extra (opcional) *)
59+
(* *)
60+
(* Utilizando el concepto de asincronía y la función anterior, crea el *)
61+
(* siguiente programa que ejecuta en este orden: *)
62+
(* *)
63+
(* - Una función C que dura 3 segundos. *)
64+
(* - Una función B que dura 2 segundos. *)
65+
(* - Una función A que dura 1 segundo. *)
66+
(* - Una función D que dura 1 segundo. *)
67+
(* - Las funciones C, B, y A se ejecutan en paralelo. *)
68+
(* - La función D comienza su ejecición cuando las 3 anteriores finalicén. *)
69+
(* *)
70+
(****************************************************************************)
71+
72+
(* Output:
73+
74+
[C] will run after 3.00 seconds | 22:02:10
75+
[B] will run after 2.00 seconds | 22:02:10
76+
[A] will run after 1.00 seconds | 22:02:10
77+
Uploaded image family.jpg
78+
[A] has been called | 22:02:11
79+
Response from server: Error 404
80+
[B] has been called | 22:02:12
81+
Successfully downloaded avengers.mp4
82+
[C] has been called | 22:02:13
83+
[D] will run after 1.00 seconds | 22:02:13
84+
Processed results, goodbye!
85+
[D] has been called | 22:02:14
86+
*)
87+
let _ =
88+
let open Lwt in
89+
let c =
90+
delay_function ~name:"C" ~seconds:3.0 (fun () ->
91+
print_endline "Successfully downloaded avengers.mp4")
92+
in
93+
let b =
94+
delay_function ~name:"B" ~seconds:2.0 (fun () ->
95+
print_endline "Response from server: Error 404")
96+
in
97+
let a =
98+
delay_function ~name:"A" (fun () ->
99+
print_endline "Uploaded image family.jpg")
100+
in
101+
(* If I create the promise and store it in a variable, nothing stops it from
102+
starting right away so I have to defer its creation until it's needed. *)
103+
let d () =
104+
delay_function ~name:"D" (fun () ->
105+
print_endline "Processed results, goodbye!")
106+
in
107+
Lwt_main.run (join [ c; b; a ] >>= d)
108+
;;
109+
110+
(* Lastly, there are other ways of handling this. What about threads? I could
111+
have used the [Thead] module with these functions: [Thread.create] and
112+
[Thread.join]; and [Thread.delay] to block each thread for N seconds. *)

0 commit comments

Comments
 (0)