Hot Objects
Hot object support is only available in certain compiler branches.
Hot objects are actors that support internal parallelism. Actor programming is traditionally about concurrency, meaning applications with asynchronous behaviours. The actor model is usually connected to a notion of decentralised control: utilisation of the underlying machine comes from saturating the system with actors so that all cores are active at all times. This is not a design that fits all systems.
Traditional Encore actors are sequential, and parallelism comes from having many actors executing sequentially, in parallel. Hot objects break away from this model by supporting two kinds of parallelism:
- Internally induced parallelism - methods can use Encore constructs that execute on multiple cores for increased throughput; or
- Externally induced parallelism - the actor can execute several messages in parallel, in general for reduced latency.
The former is useful in systems where parallelism comes from large tasks with complicated dependencies, that are not easily divided over multiple actors. The latter can be useful in designs where a single actor gets disproportionally many requests, and therefore becomes a bottleneck in the system, or where certain resources are shared through an actor, but accesses must be fast, and in particular not result in extra asynchronous indirections.
Hot Object Semantics
There are several possible configuration options for hot objects that control the interaction with a particular hot object.
Actor - the hot object works exactly like an actor. No external parallelism, only internal. Because internal parallelism comes with some overhead costs due to garbage collection, internal parallelism is allowed only inside of hot objects, so such overhead is only paid inside hot objects.
Spin lock - messages are performed synchronously and temporal conflicts are serialised with a spin lock. This fits the scenario where a resource is shared between multiple actors, and there is little contention, and operations fast.
Delegation lock - messages are performed synchronously and temporal conflicts are serialised with a delegation lock. On contention, the work is delegated to the currently executing scheduler, and a future is returned.
Lockfree - the hot object is a Kappa lockfree capability, meaning the hot object uses optimistic concurrency control internally. Thus messages may execute in parallel inside the actor object, and conflicts are handled internally by the object itself. A multi-producer multi-consumer queue is a good example of a scenario for a lockfree hot object.
Atomic - similar to the lockfree case, but messages are wrapped in transactions that roll-back on conflict. This reduces complexity in an implementation, but comes with an overhead due to transactional memory.