Use stm-queue's bounded queues, add ActorConfig, monitors, and awaitEffects - #15
Open
SamuelSchlesinger wants to merge 2 commits into
Open
Use stm-queue's bounded queues, add ActorConfig, monitors, and awaitEffects#15SamuelSchlesinger wants to merge 2 commits into
SamuelSchlesinger wants to merge 2 commits into
Conversation
stm-actor implemented bounded mailboxes as an unbounded stm-queue plus a single occupancy TVar that every send and every receive wrote, so senders and the actor conflicted on every message. stm-queue-0.2.2.0 provides bounded queues whose free capacity is tracked as split read and write credits, so capacity accounting conflicts once per `capacity` sends instead. Delegate to those queues and drop the in-house Mailbox record: enqueue retries only on a full bounded queue, tryEnqueue never retries, dequeue releases capacity, and flush releases all of it. Construct mailboxes with newQueueIO and newBoundedQueueIO instead of an atomically block. Require stm-queue >= 0.2.2.0, pinned to its git commit until it is published on Hackage. Add a multi-sender bounded mailbox test.
…defaults Introduce actWith and ActorConfig so an actor's mailbox capacity, completion handler, undelivered-message handler, and effect-failure handler are configured in one place; act, actBounded, actFinally, and actFinallyBounded become specialisations. Messages still queued when an actor stops are handed to onUndelivered in mailbox order instead of being discarded silently, and each completion effect that throws is reported to onEffectFailure, which rethrows by default to preserve the previous behaviour. Make addAfterEffect lifecycle-checked by default, matching send, with addAfterEffectUnchecked for callers that control the lifecycle. Add monitor and monitorSTM, which deliver an actor's completion to the monitoring actor's mailbox as an ordinary message rather than an asynchronous exception, and notify immediately about an already-stopped target. Add awaitEffects, which waits for the completion handler and after-effects to finish. Make murder a no-op once the actor has stopped so cleanup is not interrupted. Document that a receiver whose handles have all been dropped is stopped by the runtime with BlockedIndefinitelyOnSTM, and test it. Add a fan-in throughput benchmark comparing unbounded and bounded mailboxes. Date the 0.4.0.0 changelog entry for release.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two commits, releasing as 0.4.0.0 (Hackage has 0.3.1.1; 0.4.0.0 was never published, so the changelog entry is dated rather than bumped further).
1. Bounded mailboxes delegate to
stm-queue(commit 1)Bounded mailboxes were an unbounded
stm-queueplus a single occupancyTVarthat everysendand everyreceivewrote.stm-queue-0.2.2.0(stm-queue#3) provides bounded queues with split read/write credits, so capacity accounting conflicts once percapacitysends instead of on every message. The in-houseMailboxrecord and counter are deleted; semantics are unchanged and covered by the existing tests plus a new 8-sender × 500-message fan-in test.2. API improvements from the review (commit 2)
actWith+ActorConfig(mailboxCapacity,onCompletion,onUndelivered,onEffectFailure), withdefaultActorConfig.act/actBounded/actFinally/actFinallyBoundedare specialisations, unchanged in signature.onUndeliveredin mailbox order (only called when non-empty). Every committedsendnow reaches either a handler oronUndelivered.onEffectFailure; the default rethrows, preserving the old "first exception rethrown in the terminating thread" behaviour, but a logging handler can now replace stderr output.addAfterEffectis lifecycle-checked by default, matchingsend.addAfterEffectUncheckedkeeps the old behaviour;addAfterEffectCheckedstays as an alias.monitor/monitorSTM: message-based completion notification (Erlang'DOWN'-style) alongside exception-basedlink. Immediate delivery for an already-stopped target, transactional with the registration.awaitEffects: waits until the completion handler and after-effects have finished (set in afinally, so it fires even if effects throw).murderis a no-op once the actor has stopped, so cleanup is never interrupted. (A murder racing the transition is caught by the effect runner and recorded as an effect failure — cleanup was never truncated, contrary to what the review first suggested.)BlockedIndefinitelyOnSTM, cascading through links/monitors.stm-actor-benchmark [senders...]: fan-in throughput, unbounded vs bounded mailbox. CI now builds it under-Werror.Effect order at shutdown: lifecycle transition → links/monitors initiated →
onCompletion→onUndelivered→ user after-effects →effectsFinishedset.Release ordering
stm-queue-0.2.2.0is not on Hackage yet, socabal.projectpins it to commitb1c8f56. The main CI jobs pass with the pin; the sdist-outside-project and oldest-dependencies jobs will fail until it is published — that is what they are for. Order: merge stm-queue#3 → publish stm-queue 0.2.2.0 → drop the pin → merge this.Test plan
cabal build --enable-tests --enable-benchmarks all --ghc-options=-Werror(pinned project and a local checkout)cabal test all— 46 examples, 0 failures; 6 consecutive runs across-N2/-N4, including the GC testcabal checkandcabal haddock --haddock-for-hackageclean-N(noted in the source)