new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Temporal · all subjects

signals, queries, and updates

27 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Publish method signature and payload encoding

Publish() appends events to the stream and runs the payload converter to encode each value. The codec chain (encryption, compression, etc.) runs once on the Signal or Update envelope that carries the batch, never per item. In Go, topics carry no per-topic type binding; published values are any type.

Subscriber does not require Close

A subscriber does not need Close() because the background flusher only runs for publishers. The iterator returned by Subscribe handles re-polling, pagination, and Workflow-side log truncation transparently.

Batched publication with BatchInterval option

The BatchInterval option controls how long the client waits before shipping a batch of events. Default is typically 200 milliseconds. Use forceFlush on specific publishes to send immediately without waiting for the interval.

Publish from Workflow topic interface

Topics are bound by name using stream.Topic(name), which returns a *WorkflowTopicHandle. Repeated calls with the same name return the same handle. Call Publish() on the handle to append events. In Go, topics carry no per-topic type binding; published values are any and subscribers decode each item from its raw payload.

Publish force flush for latency control

Pass true as the forceFlush argument on a publish to wake the background flusher so the current buffer ships without waiting for the next interval. The call returns immediately after appending to the buffer and signaling the flusher; it does not wait for delivery to the Workflow or subscribers. Use force flush for latency-sensitive events like the first delta of a response or punctuated events like RETRY and STATUS_CHANGE.

Client Flush for mid-stream barriers

Use client.Flush(ctx) when a mid-stream barrier is needed. Successful completion of flush is proof that the Temporal server has received all prior publications, so subsequent work depending on those events being durable can proceed. The client stays open for further publishing afterward. Close already flushes on exit, so the explicit call is only for barriers in the middle of execution.

Publish is non-blocking with no backpressure

Publish() is non-blocking and applies no backpressure. From an Activity or client, it appends to the buffer and returns. From inside a Workflow, it appends synchronously to the in-memory log. Subscribers pull from the Workflow's log on their own schedule, so a slow subscriber does not slow down publishers. If a publisher emits faster than batches can ship to the server, the buffer grows, the process uses more memory, the stream falls further behind real time, and at the limit Signals cannot keep up.

Subscribe using iter.Seq2 iterator

Use client.Subscribe(ctx, subscribeOptions) which returns an iter.Seq2 iterator that yields a WorkflowStreamItem and an error on each step. Each item's Data is the raw payload; decode it at the call site with a payload converter. The iterator handles re-polling, pagination when a poll response hits the ~1 MB cap, and Workflow-side log truncation transparently.

SubscribeOptions controls filtering and offset

SubscribeOptions has three controls: Topics filters by name (empty or nil means all topics), FromOffset resumes from a stored global offset (zero means the beginning), and PollCooldown sets the minimum interval between polls. A single-topic convenience method streamClient.Topic("name").Subscribe(ctx, fromOffset) is equivalent to passing one name in Topics.

Heterogeneous topics subscription pattern

Every item arrives as a raw *commonpb.Payload in item.Data, so a single subscription naturally consumes multiple topics whose payload types differ. Pass the topic names in SubscribeOptions.Topics (or leave it empty for every topic), dispatch on item.Topic, and decode into the matching type. This pattern avoids the cancellation race that two concurrent subscribers would create.

Fixed sleep pattern for stream closing

One way to close a stream is to use fixed sleep. After publishing a sentinel event (e.g., StatusEvent{State: "completed"}), sleep between the terminator and the return so any in-flight poll has time to fetch the terminator before the Workflow exits. Sleep duration should allow sufficient time for subscribers to fetch the final event.

Acknowledgment handshake pattern for stream closing

An alternative to fixed sleep is the acknowledgment handshake pattern. The subscriber sends a Signal once it has the terminator; the Workflow waits up to a timeout using AwaitWithTimeout, returning as soon as the ack arrives. Use workflow.GetSignalChannel to receive the acknowledgment and a workflow.Go goroutine to listen for it.

Subscribe loop terminal status inspection

Subscribe() ends cleanly when the Workflow reaches COMPLETED, FAILED, CANCELED, TERMINATED, or TIMED_OUT, but does not distinguish among them. If the application needs to know which status (to display success or failure, log the outcome, or decide whether to retry), call temporalClient.DescribeWorkflowExecution(ctx, workflowID, "") after the loop returns to inspect the Workflow's status.

MaxRetryDuration client option for batch retry timeout

A Client retries a failed batch for up to MaxRetryDuration (default 10 minutes). If the duration elapses with the batch still pending, the client gives up, the pending batch is dropped, and a FlushTimeoutError is raised. On timeout, the dropped batch is at-most-once: it may or may not have reached the Workflow. The FlushTimeoutError terminates the background flusher, so until client.Flush(ctx) or client.Close(ctx) is called, subsequent publishes accumulate in the buffer with no flusher to ship them. MaxRetryDuration must be less than the workflow's publisher TTL to preserve exactly-once delivery.

Entity Workflow: Updates for synchronous operations with validation

Use Updates for operations that require validation and return a value. All operations on an entity go through a single Workflow, eliminating race conditions.

Entity Workflow: Signals for asynchronous events

Use Signals for asynchronous notifications that do not need responses or validation.

Entity Workflow: Queries for state inspection

Add Query handlers to expose state for monitoring and debugging without side effects.

Entity Workflow: Wait for handlers before Continue-As-New

Before calling Continue-As-New from the main Workflow method, wait for all handlers to finish. Use allHandlersFinished (TypeScript), Workflow.isEveryHandlerFinished() (Java), or workflow.all_handlers_finished() (Python) to ensure in-flight handlers complete before transitioning.

Signal handler constraint: do not call Continue-As-New from handlers

Continue-As-New must be called from the main Workflow method, never from inside a Signal or Update handler. Calling it from a handler causes non-determinism errors.

Entity Workflow pitfall: Update ID deduplication across Continue-As-New

Update IDs are scoped to a single Workflow Execution. After Continue-As-New, the same Update ID can be accepted again. Carry processed IDs in the Continue-As-New input if deduplication is needed.

Signal with Start pattern

Signal with Start starts a Workflow and delivers a Signal in a single atomic operation. If the Workflow already runs, it receives the Signal directly. Use this pattern when you want to send a message without checking whether the Workflow is running.

Request-Response via Updates pattern

Request-Response via Updates sends a request into a running Workflow and receives a validated result on the same call, using an Update handler. Use this pattern when you need a result back from the Workflow, with validation.

Event Accumulator pattern

Event Accumulator collects a stream of incoming Signals into a buffer and processes them together as a batch, rather than one at a time. Use this pattern when you receive many events and want to process them in batches.

Workflow messaging patterns overview

Workflow messaging patterns cover how external callers communicate with running Workflows — starting them on demand, sending data in, reading results back, and collecting streams of events. They build on Temporal's Signals and Updates.

Resumable Activity best practice: expose status via Query

The getStatus Query gives operations tooling visibility into where the Workflow is parked without requiring access to the Workflow history.

Resumable Activity best practice: validate correction in Signal handler

Check that the corrected account is non-empty and matches the expected format before setting the state in the Signal handler. An invalid correction parks the Workflow again, but a clear error message helps operators.

Resumable Activity pitfall: accepting corrections in wrong state

If a Signal arrives while the Activity is running (not parked), the correction should be queued and applied after the current attempt completes. The Signal handler always runs — the condition check (wait_condition) determines when the Workflow acts on it.

Give your agent this brain