To summarize:
Operations can be thought of as either blocking or compute-intensive.
A thread pool controls how many tasks can execute in parallel. An
ExecutionContext
is just another name for a thread pool.Blocking operations are best scheduled on an unbounded thread pool, while compute-intensive operations are best on a thread pool limited to the number of available processors.
An
IORuntime
has two thread pools: one for compute operations and another for blocking operations.The global
IORuntime
has a bounded compute pool and an unbounded blocking pool.IO
operations run on the compute pool by default. You can tap into the blocking pool usingIO.blocking
.
We’ve dived deep into thread pools, but there’s plenty more to explore in cats-effect’s thread model. If you’ve followed along, you’re now well equipped to understand Daniel Spiewak’s thoughts on the IORuntime design. Have a look at how it handles scheduling, and see how fibers affect the threading landscape.
Outside of Scala’s thread pools lies a whole ocean of concurrency. If you’ve a thirst for more, why not research threads in your operating system? Convert to Linux and play with its processes!
Credits
Many thanks to Fabio Labella and Daniel Spiewak for giving this a reassuring read.