Start & End events¶
Every process needs a way in and a way out. A start event is the instantiation point — the engine emits a token from it when an instance begins. An end event is a completion point — when a token arrives, that branch is done. In their plainest form both are one-line constructors that carry no trigger and simply bracket the flow; each also accepts trigger options to react to (start) or emit (end) a BPMN event. This page is the developer reference: the two types, their constructors, every option, and their runtime behavior.
Taxonomy¶
| BPMN category | Event → Start Event (§10.5.2) · End Event (§10.5.6) |
| Package | github.com/dr-dobermann/gobpm/pkg/model/events |
| Type | events.StartEvent · events.EndEvent |
| Embeds | StartEvent embeds a catch Event; EndEvent embeds a throw Event (both carry flow.BaseNode, Definitions, Triggers, Properties) |
| Implements | both: flow.Node, flow.EventNode (EventClass, Definitions), exec.NodeExecutor (Exec) · start also flow.SequenceSource, exec.NodeDataProducer · end also flow.SequenceTarget, exec.NodeDataConsumer |
| The work | start: emit a token on the outgoing flows · end: consume the token, emit/terminate on any trigger |
Where they sit in the event family: Events taxonomy.
Constructors¶
func NewStartEvent(name string, startEventOptions ...options.Option) (*StartEvent, error)
func NewEndEvent(name string, endEventOptions ...options.Option) (*EndEvent, error)
| Parameter | Meaning |
|---|---|
name |
the event's diagram name (and default id source). |
startEventOptions / endEventOptions |
zero or more options (below) — a bare start/end takes none. |
Both return an error — never panic — on an invalid combination (for example a
trigger the event class does not accept: an end event rejects a timer/conditional
trigger, a start event rejects a Cancel/Terminate trigger).
Options¶
A plain start and a plain end need no options at all — the pair below is the whole common surface:
| Option | When you reach for it |
|---|---|
| (none) | a bare start/end that just brackets the flow. |
WithTerminateTrigger(ted) |
end that tears down the whole instance, not just its branch. |
foundation.WithID(id) |
pin a stable id instead of deriving one from the name. |
The full set groups by which event accepts it. Shared options (both events)
come from foundation and data:
| Shared option | Effect |
|---|---|
foundation.WithID(id string) |
set a stable id. |
foundation.WithDoc(text, format string) |
attach documentation. |
data.WithProperties(props ...*data.Property) |
declare event-local properties. |
Start-event trigger options — the start reacts to the trigger. Accepted
triggers (startTriggers): Message, Signal, Timer, Conditional, Error,
Escalation, Compensation. A Cancel or Terminate trigger is rejected:
| Start trigger option | Effect |
|---|---|
WithMessageTrigger(med) |
instantiate on an incoming message. |
WithSignalTrigger(sed) |
instantiate on a broadcast signal. |
WithTimerTrigger(ted) |
instantiate on a timer (date/cycle/duration). |
WithConditionalTrigger(ced) |
start on a data condition (event sub-process). |
WithErrorTrigger(eed) · WithEscalationTrigger(eed) · WithCompensationTrigger(ced) |
event-sub-process / in-line sub-process starts. |
Start-event configuration options — shape a start that already carries a trigger; they do not add a trigger:
| Start config option | Effect |
|---|---|
WithParallel() |
mark a multiple start "parallel" (all triggers must fire to instantiate). |
WithInterrupting() |
event-sub-process start interrupts its parent scope — the default (§13.5.4), explicit documentation. |
WithNonInterrupting() |
event-sub-process start runs concurrently with the parent; not valid with an Error trigger (§10.5.6). |
WithCorrelationKey(key) |
the bpmncommon.CorrelationKey an instantiating message start correlates on — see Correlation & conversations. |
End-event trigger options — the end emits (or acts on) the trigger.
Accepted triggers (endTriggers): Terminate, Cancel, Error, Escalation,
Message, Signal, Compensation:
| End trigger option | Effect |
|---|---|
WithTerminateTrigger(ted) |
terminate the whole instance; the instance settles Terminated. |
WithErrorTrigger(eed) |
end the process in error, faulting the instance with the error code (§10.5.6). |
WithCancelTrigger(ced) |
abort the enclosing Transaction Sub-Process (§10.7) — valid only inside a transaction. |
WithEscalationTrigger(eed) · WithMessageTrigger(med) · WithSignalTrigger(sed) · WithCompensationTrigger(ced) |
throw the corresponding event as the branch ends. |
Each trigger has its own guide with the definition constructor and semantics — see Message, Signal, Timer, Error, Escalation, Conditional, Terminate, Compensation.
For the complete, always-current signatures run
go doc github.com/dr-dobermann/gobpm/pkg/model/events.
Build it¶
Both constructors are one line; wire them into the process like any other flow node — the start feeds the first node, the last node feeds the end:
start, err := events.NewStartEvent("start")
// ...
end, err := events.NewEndEvent("end")
// ...
for _, e := range []flow.Element{start, task, end} {
proc.Add(e)
}
flow.Link(start, task)
flow.Link(task, end)
The engine drives the full lifecycle around the pair:
engine.RegisterProcess(proc) // definition → launch template
engine.Run(ctx) // engine goroutine comes up
h, _ := engine.StartLatest(proc.ID()) // instance emits a token from the start
state, _ := h.WaitCompletion(ctx) // returns when tokens reach the ends
Run it¶
From examples/basic-process/ — start →
service task → end. After the startup banner and config dump the instance starts
at the start event, runs the task, and settles at the end event as Completed:
2026/07/27 09:17:46 INFO InstanceState Created instance_id=4817251568700577704
2026/07/27 09:17:46 INFO InstanceState Active instance_id=4817251568700577704
▶ hello, dr.Dobermann (instance started at 2026-07-27 09:17:46.86 …)
2026/07/27 09:17:46 INFO InstanceState Completed instance_id=4817251568700577704
✓ basic-process completed (Completed): start → service task (read property + RUNTIME var) → end
Terminate end event — end the whole instance at once. Attach a terminate
trigger and reaching that end tears down the entire instance, cancelling any
in-flight branches (their operation contexts are cancelled). The instance
settles Terminated, not Completed:
termEd, _ := events.NewTerminateEventDefinition()
terminate, _ := events.NewEndEvent("terminate-order",
events.WithTerminateTrigger(termEd))
From examples/terminate-end-event/ —
one branch flags fraud and terminates the instance mid-payment:
⚠ fraud-check: fraudulent order detected — terminating the process
→ process-payment: charging the card (takes ~3s)...
✗ process-payment: interrupted before it finished
Methods & runtime behavior¶
The engine drives both through these — you rarely call them directly:
| Method | Role |
|---|---|
Exec(ctx, re) ([]*flow.SequenceFlow, error) |
start: return the outgoing flows (emit the token). End: consume the token; emit its triggers, or Terminate/Cancel/fault on Terminate/Cancel/Error. |
EventClass() |
flow.StartEventClass / flow.EndEventClass. |
Definitions() / Triggers() |
inspect the event's trigger definitions. |
Clone() |
per-instance copy (config shared by reference, fresh flows). |
SupportOutgoingFlow (start) / AcceptIncomingFlow (end) |
flow-wiring guards — start takes no incoming, end takes no outgoing. |
IsInterrupting() (start) |
whether an event-sub-process start interrupts its parent. |
Behavior worth knowing:
- Start has no incoming sequence flow;
StartLatestplaces a token on its outgoing flow and execution proceeds. A trigger start (message/signal/timer) instantiates when its trigger fires. - End is a completion point, not the instance's death. Each token that
reaches a plain end ends its own branch; a process may hold several end
events and settles
Completedonce every live token has reached one. ATerminateend tears the whole instance down at once (re.Terminate()); aCancelend aborts the enclosing Transaction; anErrorend faults the instance with the error code. Terminate/Cancel are checked before the emit loop, so they win over a co-located trigger.
A plain end event ends only the branch that reached it. If other branches are still running, the instance keeps going until they too reach an end.
See also¶
- Examples:
examples/basic-process/·examples/terminate-end-event/ - Related guides: Your first process · Event data and the process contract · Terminate · Boundary events · Event sub-processes · Correlation & conversations
- Design: ADR-006 — events and subscriptions · ADR-016 — message correlation
- Full API:
go doc github.com/dr-dobermann/gobpm/pkg/model/events