Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Fearless Concurrency with JavaScript and Beyond

Evadne Wu
October 06, 2018

Fearless Concurrency with JavaScript and Beyond

Evadne Wu

October 06, 2018
Tweet

More Decks by Evadne Wu

Other Decks in Technology

Transcript

  1. Fearless Concurrency

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

    5 October 2018

    View Slide

  2. Outline
    Concepts
    Primitives
    Adoption
    Demo

    View Slide

  3. 1
    Concurrency Concepts
    Photo from Reddit

    View Slide

  4. 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.

    View Slide

  5. 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.

    View Slide

  6. 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!

    View Slide

  7. 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

    View Slide

  8. Photo by Wang Teck Heng from Pexels
    2
    Concurrency Primitives

    View Slide

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

    View Slide

  10. 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.

    View Slide

  11. Example: Document + Worker
    Document Worker

    View Slide

  12. Example: Document + Frame
    Document iFrame

    View Slide

  13. 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).

    View Slide

  14. 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.

    View Slide

  15. 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.

    View Slide

  16. 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.

    View Slide

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

    View Slide

  18. Design for Resiliency
    Document Supervisor Checkpoints
    Worker
    API

    View Slide

  19. 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]

    View Slide

  20. Photo by Sharon McCutcheon from Pexels
    3
    Adopting Concurrency

    View Slide

  21. 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.

    View Slide

  22. 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.

    View Slide

  23. Photo by Little Visuals from Pexels
    4
    Demo

    View Slide

  24. 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.

    View Slide

  25. 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.

    View Slide

  26. 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”.

    View Slide

  27. 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.

    View Slide

  28. 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.

    View Slide

  29. Photo by Pixabay from Pexels
    *
    Reference Materials

    View Slide

  30. Reference: Slide & Code
    Jake Archibald

    “In the Loop” (2018). Singapore: JS Conf Asia. Conference Talk.
    Evadne Wu

    Examples shown. GitHub Repository.

    View Slide

  31. 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.

    View Slide

  32. 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)

    View Slide

  33. Thank You
    Photo of Bear Grylls.

    Improvise. Adapt. Overcome.

    View Slide