Skip to content

Instantly share code, notes, and snippets.

@graue
Created January 5, 2013 22:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save graue/4464171 to your computer and use it in GitHub Desktop.
Save graue/4464171 to your computer and use it in GitHub Desktop.
First thoughts after reading the ConcurrentLua documentation and running the examples

Notes on ConcurrentLua 1.1

2012-Jan-5

(There is no convenient way to view ConcurrentLua's HTML documentation online, so for the time being I uploaded a copy here.)

In ConcurrentLua you apparently have to call a loop function "concurrent.loop()" to start the process. This is unlike Rust where, in your main thread, you simply spawn off a task and it starts running right away. (Does it?)

This seems to be because ConcurrentLua is doing cooperative multitasking (implemented in terms of coroutines), while Rust is doing preemptive multitasking. (Is this correct?) So a task simply keeps running until it begins to wait for a message, at which point another task will run, and so on. (Can this deadlock?)

Some aspects of ConcurrentLua seem a bit fragile. For example, a send has to manually set the "from" address:

concurrent.send(pid, { from = concurrent.self(), body = 'ping' })

It would seem safer and more convenient if you got a function parameter passed in that would always send with the correct from address. For example,

-- hypothetical, not implemented
function ping(send_func, n, pid)
    send_func(pid, 'ping')

Thinking about how Rust handles this, there doesn't seem to actually be a from address. If you clone a SharedChan and pass it to a bunch of tasks, it's not clear to a receiver which task sent which message, unless that info is, again, manually embedded in the message itself. And of course, an abstraction layer over ConcurrentLua or over Rust's channels could add that functionality. Question: What if you simply don't need a from address? Does ConcurrentLua let you omit it?

I'm not convinced of the utility of ConcurrentLua letting you register process names:

function ping(n)
    concurrent.send('pong', { from = concurrent.self(), body = 'ping' })

pid = concurrent.spawn(pong)
concurrent.register('pong', pid)
concurrent.spawn(ping, 3)

For what particular reason do you need a global mapping of names to PIDs? I'm not sure I see how a name for a task is more useful than an opaque identifier, and since tasks choose their own name (unlike the automatically-assigned PID), this introduces the chance of a collision. At best, this feature seems inessential to a concurrency lib.

The "Distributed message passing" section is interesting... this could be used to create a cluster, by having nodes on different machines. Alternatively you could run 4 nodes on the same quad-core machine to fully use the cores (otherwise I believe ConcurrentLua will only burden one core — incidentally, Wikipedia says this is typical for green threads). The bit about clustering could be quite useful. Erlang has that built into its OTP system (I think). Does Rust have a standard lib for this? Go?

In "Handling error" the docs show how you can link processes so one terminates when the other does:

function ping(n, pid)
    concurrent.link(pid)
    -- ... rest of function ...

Again, I'm skeptical of the design. Why should it be up to the task to link itself? I feel like the supervisor should handle this, like:

pong_pid = concurrent.spawn(pong)
ping_pid = concurrent.spawn(ping, 3, pong_pid)
concurrent.link(pong_pid, ping_pid)  -- hypothetical, won't really work

Also this makes it clear the relationship is two-way. The version where the task links itself might be one-way, i.e. pong dies if ping dies, but ping doesn't die if pong dies first? Does it work like that or is it two-way? The introduction in the docs isn't clear.

Also not a fan of the 'trapexit' option being a global setting:

concurrent.setoption('trapexit', true)

As with the registry mapping names to PIDs, this seems like needless global state. Why isn't the option per-task?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment