jackfirth / racket-disposable

An experimental Racket library providing an abstraction for values associated with external resources that allows automatic resource pooling, per-thread virtual construction, and monadic composition
Apache License 2.0
7 stars 0 forks source link

Make managers hold on to a value #77

Closed jackfirth closed 7 years ago

jackfirth commented 7 years ago

The internal manager abstraction is used to provide atomic access to some sort of state. However, the manager is oblivious to this state and only provides a way to execute thunks atomically. Instead, an "atomic box" abstraction could exist that essentially defines a thread that holds on to a single value and allows a client thread to send it a function it should apply to the value, possibly returning some value to the client thread. Atomic boxes are similar to Clojure atoms, but with a few key differences:

  1. No parallelism. Clojure atoms may be accessed by different (OS) threads in parallel. Racket's threading model uses a single OS thread for most concurrency operations and expects users to set up places for parallel tasks, with strict limitations on what values can be shared by places. Atomic boxes are not shareable by places because the threads communicate by sending (non-serializable) thunks to each other.
  2. No spin looping. Clojure atoms have functions applied to them by clients that compute the new value for the atom and then use compare-and-set! to atomically update. If atomic update fails due to a concurrent update, the operation is retried and the function is called on the new value of the atom. The atomic box model would have clients send a thunk to a manager thread instead, and the manager thread runs only one thunk at a time guaranteeing that concurrent updates are not possible. This also allows atomic box update operations to both update and return values to the caller in a kill-safe manner; if a thread is killed before an update to an atomic box returns a value to the thread, it's guaranteed that the update was not applied.

This would simplify the pool implementation and cleanup logic by separating a pool's concern over mutable state and thread safety from the immutable value representing that state.