most essential and appealing properties of sequential computation: understandability, predictability, and determinism. Threads, as a model of computation, are wildly nondeterministic, and the job of the programmer becomes one of pruning that nondeterminism.
cost for context switch • bad match modern NUMA architectures • locks lead to contention • not a good programming model • shared mutual state is difficult to reason about 16
/ fibres • other granularity, but basically same programming model • Event-loop (e.g. vert.x, Reactor) • very loose coupling, slightly limited, 1 x n dispatch • Actors ! • truly share-nothing, flexible, resilience-proven, m x n dispatch 18
using Actors) switched to a task level concurrency model • As a consequence, ThreadLocal becomes an anti-pattern. • Libraries that depend on them need extra work, might better be avoided • What does it mean for (blocking) I/O? 21
we can all agree on: At high levels of concurrency (thousands of connections) your server needs to go to asynchronous non-blocking. [..] any part of your server code blocks you’re going to need a thread. And at these levels of concurrency, you can’t go creating threads for every connection. From https://strongloop.com/strongblog/node-js-is-faster-than-java/
developers simply do not implement large scalable applications assuming distributed transactions. When they attempt to use distributed transactions, the projects founder because the performance costs and fragility make them impractical. [..]
year, bigger and bigger • If it fits on your machines, multiply by 10, if that fits, multiply by 1000… • Strive to scale almost linearly (N log N for some big log). Assumptions (Don’t Have to Prove These… Just Plain Believe Them) Grown-Ups Don’t Use Distributed Transactions •The apps using distributed transactions become too fragile… • Let’s just consider local transactions. ! Multiple disjoint scopes of serializability Want Scale-Agnostic Apps • Two layers to the application: scale-agnostic and scale-aware • Consider scale-agnostic API Scale Agnostic Code Scale-Aware-Code Application Upper Layer Lower Layer Scale Agnostic API
source of unnecessary failure and of contention. It can usually be avoided. Generally, local transactions and at-least-once delivery can be used instead. The Saga Pattern provides a pragmatic solution for „all-or- nothing“ in a distributed system.
is changing, moving towards event sourcing and immutability. This is a great match for reactive systems. The „all-or-nothing“ problems are closely related to wanting a global truth at a point in time. But what is now… the illusion of present… result of series of events..
sub-thread level concurrency. Accept it, embrace it. • Use asynchronous I/O. If you really can’t, isolate. • Do not use distributed transactions. If you really must, isolate. 42
developed for thread-per- request, synchronous I/O. Application servers are not of much use anyway, nobody uses them as containers for multiple applications. So effectively they’re just a library dependency. The ops convenience can be provided by other tools.
sub-thread level concurrency. Accept it, embrace it. • Use asynchronous I/O. If you really can’t, isolate. • Do not use distributed transactions. If you really must, isolate. • Don’t use an application server / servlet container. 47
unit of concurrency in your code, or • You use blocking I/O (without clear separation), or • You use 2-phase-commit across systems, or • You use a Java EE Application Server / Servlet Container Then your application is not reactive.