feat: async dispatch support - #1
Merged
Merged
Conversation
- Add async: Boolean = false to @subscribe annotation - Add asyncExecutor: Executor? constructor param to SimpleEventBus - Add async flag to ListenerEntry and lambda subscribe overloads - Add postAsync(event): CompletableFuture<T> to EventBus and TypedEventBus - Implement buildDispatchChain with priority-ordered CompletableFuture chaining; async entries via thenApplyAsync, sync entries via thenApply after async steps - Add AsyncCancellableGuard: makes cancellation thread-safe for async dispatch without requiring @volatile on user isCancelled fields; uses happens-before polling via the future chain and flushes back to the event after join - Add factory overloads: EventBus(executor), EventBus(executor, handler), createWithHandler(executor, handler) - Delegate postAsync and async subscribe through TypedEventBusAdapter - Add AsyncDispatchTest (28 tests) covering all async scenarios - Add AsyncDispatchBenchmark - Update ABI snapshot, Cancellable KDoc, postAsync KDoc, README
- postAsync: short-circuit to sync loop when no async handlers present - post KDoc: document CompletionException on executor rejection - AsyncDispatchBenchmark: fix syncPostWithExecutorConfigured to use a dedicated sync-only bus; add asyncFallbackToSync benchmark - AsyncJavaInteropTest: add Java-facing async API coverage - AsyncCancellableGuard: remove trailing blank lines
- post: route CompletionException from .join() to exceptionHandler; no-throw contract preserved; postAsync still propagates (documented) - Subscription.cancel(): private cancelled flag prevents spurious dispatchCache.clear() on double-cancel - DispatchList: pre-compute hasAnyAsync at cache-build time; removes list.any scan on every dispatch - chainAsync/chainSync: thenApply -> thenRun; removes redundant Unit - Executor-rejection tests, subscription idempotency tests - Split JavaUsageExample into per-feature files matching Kotlin layout - README: linked example tables, Maven badge -> Meteor Maven, @volatile mentions removed
Apply consistent doc structure to all public-facing files: - One-sentence imperative lead on every method - @param on all non-obvious parameters, @return on all non-void methods - Kotlin snippet first, Java snippet only where the call site differs - Removed internal implementation details from user-facing docs - Subscription.cancel clarifies idempotency; close clarifies alias role - TypedEventBus methods aligned with EventBus counterparts
- subscribeAll KDoc (EventBus + TypedEventBus): wildcards are always sync; when following an async step they run on the completing async thread, not the posting thread; thread-local state (e.g. MDC) will silently see the wrong context on a bus with async handlers - AsyncDispatchTest: wildcard between async typed handlers preserves mutation visibility; wildcard fires in priority order within the chain; wildcard in the sync prefix runs on the posting thread
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.
Adds opt-in per-handler async execution via
Executorinjection,preserving all existing dispatch guarantees (priority ordering, mutation visibility, cancellation) across thread boundaries.
What's new
EventBus(executor): async-capable bus construction@Subscribe(async = true)andsubscribe(..., async = true): per-handler opt-inpostAsync(event): non-blocking dispatch returningCompletableFuture<T>post(event): unchanged contract; blocks if async handlers are presentTypedEventBus.postAsync: delegation to underlying busAsyncCancellableGuard: automatic thread-safe cancellationAsyncDispatchBenchmark: postAsync vs sync post across all-sync, all-async, mixed scenariosGuarantees preserved
thenRunchainingasync = truefalls back silently to syncOut of scope
asyncflag onsubscribeAll(wildcards are always sync by design)kanal-coroutinessubmodule (possibly in the future)