EEZ Studio User Actions: Distinguish a Data Output from Completion

An EEZ Studio User action may emit a useful data value before the operation is complete. Treating that output as the caller's completion signal can enable the next command too early. The reverse mistake also occurs: the caller waits for a result value even though the User action only reaches its sequential completion path.

The official Output documentation describes forwarding data through the corresponding caller output. The End documentation describes a different control-flow role. For this article, the scope is a standard User action called by a parent Flow, not page termination or Dashboard shutdown.

The distinction is visible in the pinned Output implementation and End implementation. Output maps a received value to the parent component's data output. End, for an action with the relevant parent, propagates through the caller's sequence output.

Give each connector a business meaning

Consider a User action that validates a request, performs work and reports a final result. A data output might carry a validation detail or a completed result. Its meaning must be stated; the mere presence of data does not tell the caller which milestone it represents.

Name outputs according to that meaning. “Progress,” “validated request” and “final result” express different contracts. A generic output named “value” leaves callers to infer timing from whatever happened in the first example.

Define the sequence continuation separately. If the caller may start another operation only after cleanup is complete, route the completion path after that cleanup. Do not rely on a data output that happens to be produced near the end of the happy path.

A User action Output sends a value to the caller data connector; a deliberately placed End follows the action-parent sequence continuation path.
Original User action interface model. End is not shown as automatic cleanup or cancellation of every native operation.

Test data and completion with independent sinks

Create a diagnostic caller with one sink for the User action's data output and another for its sequential continuation. Give them separate counters and logs. Then construct a simple action that sends a recognizable value and reaches End through a deliberate path.

Observe the two milestones independently. A single status label is a poor diagnostic because one update can overwrite another. The test should establish which value was delivered and when the caller's completion path became eligible, without assuming those observations are interchangeable.

Next place a harmless delayed step between the data output and End in a diagnostic design that supports that sequence. The purpose is to reveal any caller that incorrectly interprets the earlier value as completion. This is a proposed test; no User action was executed here.

Every supported outcome needs a deliberate contract

List success, validation rejection, cancellation and supported runtime errors. For each, specify whether the caller receives data, receives sequential continuation, receives a separate error route or remains waiting by design. An outcome that produces neither expected signal can leave the caller's busy state stuck.

Do not force all outcomes into an undifferentiated success continuation merely to make the spinner stop. If completion means “the attempt has ended,” carry the success or failure result separately. If continuation means “the operation succeeded,” use an explicit alternative for rejection and failure.

An error handler should be reviewed for its actual placement and supported failure routes. This article does not claim that adding End to one handler catches every error or completes every pending request.

End is not proof of universal cleanup

The inspected End function's action-parent path propagates a sequence output. That narrow observation does not prove that all native resources were released, every queued child operation was cancelled or every asynchronous callback can no longer arrive.

Perform required cleanup before reporting completion, using the resource owner's actual API. If an external operation continues after the Flow reports completion, the caller must either know that contract or wait for a different milestone. A component name is not evidence of cancellation semantics.

Similarly, a late callback should be associated with the request that started it. Otherwise, it may publish a result into a caller that has already moved to another request. That is an application lifetime issue to test, not an automatic guarantee supplied by Output or End.

Check the actual runtime boundary

The code links are pinned to framework commit dc9af2d5004201d6c31273a4c4fcfe27fc20c234. The editor reference used in this investigation is EEZ Studio v0.29.0, but those references do not establish that every generated runtime is identical. Confirm the parent-action arrangement and the runtime included by the project.

Keep the regression cases small: data without completion, completion without a meaningful result, ordinary success and one supported failure. The first two are particularly useful for exposing callers that have accidentally conflated connectors.

The acceptance record should say exactly what a caller may conclude from each signal. A data value proves that a particular value was emitted. A deliberately placed completion path can establish that the defined operation milestone was reached. Neither should silently stand in for the other.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *