Elixir Findings: Asynchronous Task Streams

Using Enum.map together with Task.async and Task.await to increment a list of numbers

Simplicity

Using Task.async_stream to increment a list of numbers
Using Task.async_stream with a function reference

Lazy Evaluation

#Function<1.111840141/2 in Task.build_stream/3>
Calling only Task.async_stream won't run the tasks, use something like Enum.to_list to fetch the results
[ok: 2, ok: 3, ok: 4, ok: 5, ok: 6, ok: 7, ok: 8, ok: 9, ok: 10, ok: 11]
Retrieving only the function call result from the list of tuples
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

Concurrency

With :max_concurrency set to 2 only a maximum of two tasks are running in parallel at any given time
[
ok: {1, 1549319667100},
ok: {2, 1549319667100},
ok: {3, 1549319668102},
ok: {4, 1549319668102},
ok: {5, 1549319669102},
ok: {6, 1549319669102},
ok: {7, 1549319670103},
ok: {8, 1549319670103},
ok: {9, 1549319671104},
ok: {10, 1549319671104}
]

Timeouts

Task.async_stream default timeout value is of 5000 milliseconds so the stream won't finish processing with this code.
** (exit) exited in: Task.Supervised.stream(5000)
** (EXIT) time out
(elixir) lib/task/supervised.ex:276: Task.Supervised.stream_reduce/7
(elixir) lib/enum.ex:3015: Enum.reverse/1
(elixir) lib/enum.ex:2649: Enum.to_list/1
By specifying the :timeout value on Task.async_stream the stream of tasks finishes processing
  • :exit - This is the default value. In this situation the process that spawned the task exits
  • :kill_task - In this case, only the task that timed out is killed. If the first task in the stream fails the others might be able to still finish. The value emitted for this task is the tuple {:exit, :timeout}
Testing different timeout behaviours with :on_timeout
1 - 9000 milliseconds
2 - 8000 milliseconds
3 - 7000 milliseconds
4 - 6000 milliseconds
5 - 5000 milliseconds
6 - 4000 milliseconds
7 - 3000 milliseconds
8 - 2000 milliseconds
9 - 1000 milliseconds
10 - 0 milliseconds
[
exit: :timeout,
exit: :timeout,
exit: :timeout,
exit: :timeout,
exit: :timeout,
ok: 6,
ok: 7,
ok: 8,
ok: 9,
ok: 10
]

Conclusion

--

--

--

http://dino.codes | Twitter: https://twitter.com/joaofcosta_ | Github: https://github.com/joaofcosta

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

💪Deploying GitHub Enterprise Server on Azure using Bicep

Sustainability — Blending the architectural complexity mix

Software Testing In Accelerated System

Reflecting on My Codesmith Journey

Docker — The Beginners way

NVIDIA Enters the CPU Market

Nested classes in Java

7 Tips To Learn Programming As A Self-Taught

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Dino Costa

Dino Costa

http://dino.codes | Twitter: https://twitter.com/joaofcosta_ | Github: https://github.com/joaofcosta

More from Medium

Managing Docker, Elixir private modules and SSH

Correct file ownership when mounting local folders in Docker on Linux

Listing Modules under a Namespace in Elixir

Avoiding Visual Studio Code extension reinstalls on running Docker containers