[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: [ANN] article: Structured concurrency and Lua
- From: Sean Conner <sean@...>
- Date: Fri, 23 Sep 2022 02:08:29 -0400
It was thus said that the Great John Belmonte once stated:
> On Tue, Sep 20, 2022 at 10:21 PM Jorge Visca <xxopxe@gmail.com> wrote:
>
> > I wonder how would you handle waiting on several
> > signals?
>
> First, it needs cancellation (coming in part 3).
>
> Given that, I usually implement a `wait_any()` utility. The inputs can be
> any function that uses return of control to signal the event. (For
> example, the async_wait() method of Event.) Then:
>
> ```
> -- run these functions concurrently; when one returns, cancel the others
> async_wait_any(
> event_foo.async_wait,
> async_wait_for_bar,
> async_do_baz,
> ...)
> ```
I've been playing around with my own implementation of this for
org.conman.nfl [1]. I got cancellation working (using coroutine.close()),
so the following bit of code works as intended:
local tcp = require "org.conman.nfl.tcp"
local nursery = require "nursery"
local function get_quote(list)
local conn = tcp.connect('brevard.conman.org','qotd')
if conn then
for line in conn:lines() do
table.insert(list,line)
end
conn:close()
end
end
-- get_gopher and get_gemini not shown, but are similar
-- in nature.
local data_quote = {} -- used to accumulate the data
local data_gopher = {} -- from each of these services
local data_gemini = {}
do
local _ <close> = nursery(1) -- I don't care about the name
:spawn(get_gemini,data_gemini) -- so '_' is it!
:spawn(get_gopher,data_gopher)
:spawn(get_quote,data_quote)
end
The nursery:spawn() function returns the nursery so calls can be chained
like this. The call nursery(1) sets up a timeout for the entire nursery
collection and will cancel any current jobs still running in the nursery.
You can also write it as:
nursery() -- no timeout specified, so take as long as you like
:spawn(get_gemini,data_gemini)
:spawn(get_gopher,data_gopher)
:spawn(get_quote,data_quote)
:wait() -- this is also the __close() metamethod
I also support a wait_any(), which will wait until one of the jobs
finishes, then cancel the others:
nursery()
:spawn(get_gemini,data_gemini)
:spawn(get_gopher,data_gopher)
:spawn(get_quote,data_quote)
:wait_any()
I'm awaiting futher installments of the series, as I can't follow the
documentation for Python Trio, since I don't do Python.
-spc
[1] My event/coroutine driver:
https://github.com/spc476/lua-conmanorg/blob/master/lua/nfl.lua