Yep, this is basically the style I'm using in luvit's new package manager
(luvit/lit). It's gets a little tricky around error handling, but most
that can be handled in the spawn and parallel helpers.
On Feb 12, 2015 2:50 AM, "Connor McKay" <[email protected]> wrote:
> I discovered Luvit about a month ago, and have become very excited about
> the possibilities it holds. I had never used Lua before, but I am quickly
> falling in love with its clean, minimalist design (what Javascript
> could/should have been), and its coroutines. I've read a few posts on this
> list discussing alternate ideas for an API that would break away from the
> callback-hell of Node, and I wanted to see if it was possible to create an
> API that would perfectly mimic synchronous operations, while still allowing
> asynchronous parallelism and background work. Below is a minimal example
> (that doesn't actually use Luvit itself):
>
> callbacks = {}
>
> function event_loop()
> while (#callbacks > 0) do
> time = os.time()
> for i, v in ipairs(callbacks) do
> if time >= v[1] then
> table.remove(callbacks, i)
> v[2]()
> break
> end
> end
> end
> end
>
> -- Callback style functions
>
> function set_timeout(seconds, cb)
> table.insert(callbacks, {os.time() + seconds, cb})
> end
>
> function load_name(cb)
> set_timeout(3, function() cb("Bob") end)
> end
>
> -- Synchronous style functions
>
> function pause(seconds)
> local co = coroutine.running()
> set_timeout(seconds, function()
> assert(coroutine.resume(co))
> end)
> coroutine.yield()
> end
>
> function get_name()
> local co = coroutine.running()
> load_name(function(name)
> assert(coroutine.resume(co, name))
> end)
> return coroutine.yield()
> end
>
> -- Parallelization functions
>
> function spawn(func)
> coroutine.wrap(func)()
> end
>
> function parallel(...)
> local args = {...}
> local done = 0
> local co = coroutine.running()
> function task_done()
> done = done + 1
> if done == #args then
> assert(coroutine.resume(co))
> end
> end
> for i, func in ipairs(args) do
> coroutine.wrap(function()
> func()
> task_done()
> end)()
> end
> coroutine.yield()
> end
>
> -- The main program itself
>
> function main()
> print("Hello main, pause 2")
> pause(2)
>
> print("Getting name...")
> local name = get_name()
> print("Name was " .. name)
>
> parallel(function()
> print("Parallel 1, pause 3")
> pause(3)
> print("Done parallel 1")
> end,
> function()
> print("Parallel 2, pause 3")
> pause(3)
> print("Done parallel 2")
> end)
>
> print("Done parallel, in main")
>
> spawn(function()
> print("In spawn 1, pause for 5 seconds")
> pause(5)
> print("Done with spawn 1")
> end)
>
> spawn(function()
> print("In spawn 2, pause for 5 seconds")
> pause(5)
> print("Done with spawn 2")
> end)
>
> print("Main pause 2")
> pause(2)
>
> print("Done main")
> end
>
> coroutine.wrap(main)()
>
> event_loop()
>
> This is little more than a proof of concept at the moment, but I thought
> it might be useful in the API design discussion.
>
> Thanks,
> Connor McKay
>
> --
> You received this message because you are subscribed to the Google Groups
> "luvit" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.
>
--
You received this message because you are subscribed to the Google Groups
"luvit" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.