Slide 1

Slide 1 text

Fearless Concurrency
 with JavaScript & Beyond Evadne Wu Head of Exam Systems, Faria Education Group [email protected] twitter.com/evadne revised 5 October 2018

Slide 2

Slide 2 text

Outline Concepts Primitives Adoption Demo

Slide 3

Slide 3 text

1 Concurrency Concepts Photo from Reddit

Slide 4

Slide 4 text

Concurrency Parallelism Concurrency: multiple tasks run It is possible to have concurrency on even a single thread. Parallelism: multiple tasks run at the same time True parallelism is not possible without multiple concurrently active execution contexts, and can be extremely fragile in code written for Web applications. ≠

Slide 5

Slide 5 text

Some Benefits of Parallelisation Jank Reduction Frees up the main thread to respond to user input, resulting in a snappier experience. Additional executors might also be used to wrap otherwise synchronous operations, as long as the underlying platform allows. Better Utilisation of Resources Additional execution contexts can better utilise available cores when there is a non- trivial amount of work to be done on the client.

Slide 6

Slide 6 text

Parallelisation Pitfalls Parallelisation might have diminishing returns, because parts of the work cannot be parallelised. Essentially true for things that will be shown to the end user (in the UI). Breaking work down into multiple pieces might introduce additional overhead. This results in a net increase of processing time and could make things worse!

Slide 7

Slide 7 text

Theoretical speedup is always limited by the part of the task
 that cannot benefit from the improvement. Amdahl’s Law [1967] Slatency(s) = 1 (1 − p) + p s

Slide 8

Slide 8 text

Photo by Wang Teck Heng from Pexels 2 Concurrency Primitives

Slide 9

Slide 9 text

Preemption vs Event-Driven Single Context: setTimeout / Promise / Callbacks No Parallelism. Event-driven. No pre-emption. Multiple Contexts: Channel Messaging API Parallelism. Preemption possible.

Slide 10

Slide 10 text

Command & Control The script running in your Document (main execution context) is responsible for managing the Control Flow. It can spawn multiple execution contexts, or just schedule work to be done. It has to aggregate work results and present these to the end user.

Slide 11

Slide 11 text

Example: Document + Worker Document Worker

Slide 12

Slide 12 text

Example: Document + Frame Document iFrame

Slide 13

Slide 13 text

Cross-Context Messaging Each separate Execution Context needs to start somewhere. They need to be seeded with work to be done, and they need to convey the results back. This is usually done with the Channel Messaging API (postMessage calls and message events).

Slide 14

Slide 14 text

Data Movement in Messaging worker.postMessage(message, [transfer]); The data may be any value or JavaScript object handled by the structured clone algorithm, which includes cyclical references.

Slide 15

Slide 15 text

Data Movement in Messaging worker.postMessage(message, [transfer]); An optional array of Transferable objects to transfer ownership of. But bitmap support isn’t everywhere yet.

Slide 16

Slide 16 text

Design Considerations Cancellation (Pre-Emption) of Unwanted Work If the user no longer wants to do something, in-progress work can be cancelled. Isolation & Handling of Errors Instead of doing everything in a single Worker, consider a supervision tree, which allows cleaner code, partial failures/restarts and general isolation of failures.

Slide 17

Slide 17 text

What if the Worker is stuck in a bad state or too busy to be cancelled? Bad Example: the lone Worker Document Worker

Slide 18

Slide 18 text

Design for Resiliency Document Supervisor Checkpoints Worker API

Slide 19

Slide 19 text

Caveat > Any sufficiently complicated concurrent program in another language contains an ad-hoc, informally-specified, bug-ridden, slow implementation of half of Erlang. Robert Virding [2008]

Slide 20

Slide 20 text

Photo by Sharon McCutcheon from Pexels 3 Adopting Concurrency

Slide 21

Slide 21 text

Think First Can the Problem be designed away? Maybe the Problem should be dealt with server-side? Can the Problem actually be dealt with concurrently? Amdahl’s Law, etc. — maybe only parts of the Problem can be solved concurrently? Additional complexity needs to be justified.

Slide 22

Slide 22 text

Divide & Conquer Measure twice and cut once. Be conscious of both execution and maintenance overhead. Use Promises to manage control flow. Resolve the appropriate Promise in message event handlers, to avoid nested callbacks or other complications. Allows maintenance of a single-threaded illusion — part affordance and part burden.

Slide 23

Slide 23 text

Photo by Little Visuals from Pexels 4 Demo

Slide 24

Slide 24 text

Demo 1: Sleep Sort Messages are causally ordered and buffered. What’s sent first will be received first. Busy workers cause buildup of messages. Web Workers are not threads. You can create many, many more Workers than the number of threads that a healthy system is capable to support. System stability may suffer, though, and additional Workers might block/fail on creation since Workers are implemented with Threads which may be subject to quota.

Slide 25

Slide 25 text

Demo 2: Parallelisation Overhead There is a mechanical cost to parallelisation You need to spend time setting up and tearing down contexts, aggregating results, and so on. There is also a mental cost to parallelisation At least in Web applications, parallelisation is not straightforward and usually carry quite a big maintenance burden.

Slide 26

Slide 26 text

Demo 3: Error Isolation iFrames are currently run within the same context. Unlike Web Workers, there is no true isolation between the host document and its iFrames. Chrome’s ongoing work on top-level document isolation is supposed to help with this though. Cancelling something is as important as running it A Web application that can’t regulate itself is an app that goes “Aw Snap”.

Slide 27

Slide 27 text

Demo 4: Teasing the Compositor Audio/Visual things are hard to parallelise There is only one compositor per document at this time. Even in case of each iFrame being driven from a separate process, composition is non-trivial. Some things can’t be poly-filled You can fake the illusion of a feature, like Offscreen Canvas, but reality catches up with you, eventually. Sometimes it is never as good as native.

Slide 28

Slide 28 text

Demo 5: iFrame Spawnfest If you really need to use iFrames, don’t draw anything Even the simplest thing can slow down in great numbers. Don’t use iFrames for concurrency They are not isolated from each other. You can use multiple windows, though, as long as the browser does not decide to offload or throttle background contexts.

Slide 29

Slide 29 text

Photo by Pixabay from Pexels * Reference Materials

Slide 30

Slide 30 text

Reference: Slide & Code Jake Archibald
 “In the Loop” (2018). Singapore: JS Conf Asia. Conference Talk. Evadne Wu
 Examples shown. GitHub Repository.

Slide 31

Slide 31 text

Reference: Documentation MDN (Mozilla Developer Network) Web Docs.
 Channel Messaging API. The Chromium Projects
 Chromium Security — Site Isolation.
 Chromium Design Document — Site Isolation.
 Blink Workers. WHATWG
 Living Standard for Web Workers.

Slide 32

Slide 32 text

Reference: Miscellaneous Source Code Locations Firefox: dom/workers WebKit: webkit/Source/WebCore/workers Blink: See “Worker Code Locations” in Blink Workers. Bugs etc. Blink: Can’t start nested workers (#31666)

Slide 33

Slide 33 text

Thank You Photo of Bear Grylls. Improvise. Adapt. Overcome.