EffectExecutorImpl

class EffectExecutorImpl(effectRegistry: EffectRegistry, context: suspend () -> ExecutionContext, failurePolicy: EffectFailurePolicy = EffectFailurePolicy.CONTINUE, logger: TelekLogger = TelekLogger.NoOp) : EffectExecutor

Looks up a handler per effect in effectRegistry and runs it. context is resolved once per execute call — transport-specific executors (e.g. telegramEffectExecutor()) use this to supply an ExecutionContext that may only become available after telek itself is constructed (e.g. once a bot instance exists), without Telek needing to own or track that lifecycle.

Synchronous handlers run on telekIoDispatcher, since telek ships handlers that do blocking I/O (kotlin-telegram-bot's client) — this keeps them off whatever dispatcher Telek's per-chat workers run on. Async handlers (see AsyncEffectHandler) are handed to the caller-supplied dispatchAsync as-is; where they actually run is up to the caller.

Constructors

Link copied to clipboard
constructor(effectRegistry: EffectRegistry, context: suspend () -> ExecutionContext, failurePolicy: EffectFailurePolicy = EffectFailurePolicy.CONTINUE, logger: TelekLogger = TelekLogger.NoOp)

Functions

Link copied to clipboard
open suspend override fun execute(effects: List<Effect>, dispatchAsync: (key: Any?, work: suspend () -> Event?) -> Unit): List<EffectResult>

Runs effects and returns one EffectResult per synchronous effect, in order. An effect registered as async (see EffectRegistry.registerAsync) produces no EffectResult here — instead, dispatchAsync is called with the effect's Debounced.debounceKey (or null if it isn't Debounced) and a suspend block that runs that handler and returns its Event; the caller (telek's Telek) is responsible for actually launching that block somewhere that outlives this execute call, for cancelling a previous same-key launch first, and for routing a non-null Event back into the FSM. dispatchAsync is expected to be fire-and-forget from this method's perspective.