concurrency call to arms

John Belmonte john at neggie.net
Thu Aug 16 20:30:26 UTC 2018


This is actually not about war; rather the peace and prosperity 
of people writing concurrent programs.

(Andrei, I hope you are reading and will check out
https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/ and
https://vorpus.org/blog/timeouts-and-cancellation-for-humans/)

Recently I've been working with Trio, which is a Python async 
concurrency library implementing the concepts described in the 
articles above.  A synopsis (Python):

     with open_task_container() as container:
         container.start_task(a)
         container.start_task(b)
         await sleep(1)
         container.start_task(c)
         # end of with block

     # program continues (tasks a, b, c must be completed)...

The point is that tasks started in the container's scope will not 
live past the scope.  Scope exit will block until all tasks are 
complete (normally or by cancellation).  If task b has an 
exception, all other tasks in the container are cancelled.

What this means is that task lifetimes can be readily understood 
by looking at the structure of a program.  They are tied to 
scoped blocks, honor nesting, etc.

Similar for control of timeouts and cancellation:

     with fail_after(10):  # raise exception if scope not 
completed in 10s
         reply = await request(a)
         do_something(reply)
         reply2 = await request(b)
         ...

These are novel control structures for managing concurrency.  
Combining this with cooperative multitasking and explicit, 
plainly-visible context switching (i.e. async/await-- sorry 
Olshansky) yields something truly at the forefront of concurrent 
programming.  I mean no callbacks, almost no locking, no 
explicitly maintained context and associated state machines, no 
task lifetime obscurity, no manual plumbing of cancellations, no 
errors dropped on the floor, no shutdown hiccups.  I'm able to 
write correct, robust, maintainable concurrent programs with 
almost no mental overhead beyond a non-concurrent program.

Some specimens (not written by me):
     #1:  the I/O portion of a robust HTTP 1.1 server 
implementation in about 200 lines of code.  
https://github.com/python-hyper/h11/blob/33c5282340b61ddea0dc00a16b6582170d822d81/examples/trio-server.py
     #2: an implementation of the notoriously difficult "happy 
eyeballs" networking connection algorithm in about 150 lines of 
code.  
https://github.com/python-trio/trio/blob/7d2e2603b972dc0adeaa3ded35cd6590527b5e66/trio/_highlevel_open_tcp_stream.py

I'd like to see a D library supporting these control structures 
(with possibly some async/await syntax for the coroutine case).  
And of course for vibe.d and other I/O libraries to unify around 
this.

I'll go out on a limb and say if this could happen in addition to 
D addressing its GC dirty laundry, the language would actually be 
an unstoppable force.

Regards,
--John



More information about the Digitalmars-d mailing list