Sub-processes & reuse¶
Composition keeps a large process readable: fold a stretch of work into one
node, invoke a whole process by reference, or wrap a fragment so a failure
abandons it cleanly. gobpm offers three composition activities, all in
github.com/dr-dobermann/gobpm/pkg/model/activities. They split on one axis —
whether the inner work runs in the same instance's scope tree or as a
separate child instance:
- an embedded Sub-Process opens a child scope inside the running instance and runs an inner graph you build in place;
- a Transaction Sub-Process is that same scope with ACID-like abort — a Cancel inside compensates completed work and unwinds it;
- an Ad-Hoc Sub-Process is that same scope with no sequence flows inside: what runs next is answered at runtime by a Router rather than fixed by the model;
- a Call Activity parks the caller's token and runs a separately registered process as its own isolated child instance.
This is the family map — the class tree, every member with its role and page, and the attributes and options they share. Each member has its own reference page linked below.
The family¶
classDiagram
class Activity {
I/O parameters
boundary events
loop / multi-instance
compensation
}
class SubProcess {
inner graph (same instance)
+IsTransaction() bool
+IsEventSubProcess() bool
}
class CallActivity {
called process (child instance)
+CalledKey() string
+CalledVersion() int
}
Activity <|-- SubProcess
Activity <|-- CallActivity
SubProcess <.. Transaction : WithTransaction()
SubProcess <.. EventSubProcess : WithTriggeredByEvent()
SubProcess <.. AdHoc : WithAdHoc()
SubProcess and CallActivity are the two concrete types. Transaction,
Event Sub-Process and Ad-Hoc are not separate types — they are a plain
SubProcess tagged by a construction option (WithTransaction /
WithTriggeredByEvent / WithAdHoc), reported at runtime by IsTransaction()
/ IsEventSubProcess() / IsAdHoc(). The three markers are mutually
exclusive.
Members¶
Most composition is one of the first two rows; reach past them only when you need transactional abort or event-triggered handling.
| Type | Role | Page |
|---|---|---|
SubProcess |
a nested scope in the same instance: an activity that also contains its own inner graph, entered by a token and drained as a unit. | Embedded Sub-Process |
CallActivity |
invoke a separately registered process as an isolated child instance; the caller's token parks until it finishes. | Call Activity |
SubProcess + WithTransaction() |
the embedded scope with ACID-like abort: a Cancel End Event inside compensates completed work and leaves through the Cancel boundary. | Transaction Sub-Process |
SubProcess + WithTriggeredByEvent() |
an Event Sub-Process: a scope-armed handler entered only when its single triggered Start Event fires — not by a sequence flow. | Event sub-processes |
SubProcess + WithAdHoc(r) |
an Ad-Hoc Sub-Process: inner activities with no flows between them, whose order a Router decides at runtime. | Ad-Hoc Sub-Process |
Where these sit in the wider activity family (Tasks, Sub-Process, Call Activity): Activities taxonomy.
Constructors¶
func NewSubProcess(name string, opts ...options.Option) (*SubProcess, error)
func NewCallActivity(name, calledKey string, opts ...options.Option) (*CallActivity, error)
| Parameter | Meaning |
|---|---|
name |
the activity's diagram name (and default id source). |
calledKey |
(Call Activity) the registry key of the callable process; resolved at call time to latest-at-launch, or the version pinned by WithCalledVersion. |
opts |
zero or more options (below). |
Both return an error — never panic — on an invalid combination (e.g. a mutually-exclusive marker pair, or a bad option value).
A
SubProcess's inner elements are added like a process's:Addeach inner node into the sub-process, thenflow.Linkthem within the container. A flow must never cross the sub-process boundary. ACallActivityhas no inner graph to build — its body is the called process.
Shared attributes¶
Both types embed the same Activity base and carry its attributes and
associations:
| Attribute | Method(s) | Notes |
|---|---|---|
| I/O parameters | Properties(); Call Activity also CallInputs() / CallOutputs() |
the Call Activity's declared inputs/outputs are its call contract (BPMN §10.4 direct mapping by name). |
| Boundary events | AddBoundaryEvent(be) / BoundaryEvents() |
attach interrupting/non-interrupting boundary events — see Boundary events. |
| Loop / multi-instance | LoopCharacteristics() (set via WithLoop / WithMultyInstance) |
repeat the whole composition — see Standard Loop, Multi-Instance. |
| Compensation | ForCompensation() (set via WithCompensation) |
mark the activity a compensation handler, armed off the normal flow. |
| Introspection | ActivityType(), NodeType(), Node() |
the activity's BPMN kind and its node identity. |
| Default flow | DefaultFlow() / SetDefaultFlow(id) |
the unconditional outgoing flow when the activity has conditional splits. |
The engine drives both through Exec(ctx, re) ([]*flow.SequenceFlow, error) —
you rarely call it directly. A SubProcess additionally exposes container
methods (Add, Remove, DataObjects, DataStoreReferences) and the runtime
predicates IsTransaction() / IsEventSubProcess(); a CallActivity exposes
CalledKey() / CalledVersion() and the resolved call parameters
(CallInputs() / CallOutputs()).
Options¶
Two members take construction-time options; both option types satisfy
options.Option (each has an Option() marker method), so you pass them
straight to the constructor.
Sub-Process markers (SubProcessOption) — mutually exclusive; a plain embedded
Sub-Process needs neither:
| Option | Effect |
|---|---|
WithTransaction(opts...) |
mark the scope a Transaction Sub-Process (BPMN §10.7): only Cancel End/boundary is permitted, and reaching a Cancel inside triggers the ACID-like abort. |
WithTriggeredByEvent() |
mark the scope an Event Sub-Process (BPMN §13.5.4): a scope-armed handler entered by its single triggered Start Event, not by a flow. |
WithAdHoc(r adhoc.Router) |
mark the scope Ad-Hoc (BPMN §13.3.5): its inner activities carry no sequence flows, and the Router answers what runs next. Refined by WithAdHocOrdering / WithAdHocManualSelection / WithAdHocCancelRemaining / WithAdHocCompletion. |
Call-Activity option (CallActivityOption):
| Option | Effect |
|---|---|
WithCalledVersion(v int) |
pin the call to an exact registered version (1-based, per definition versioning). Without it the call binds the newest version registered at the moment it executes. |
Both types also accept the shared activity options (ActivityOption) from
the base — the same WithParameters / WithoutParams / WithCompensation /
WithLoop / WithMultyInstance / WithStartQuantity /
WithCompletionQuantity documented on the
Activities taxonomy.
A minimal Transaction Sub-Process is just the marker on a normal sub-process:
sp, _ := activities.NewSubProcess("charge", activities.WithTransaction())
// build its inner graph; a Cancel End Event inside aborts the scope.
See also¶
- Members: Embedded Sub-Process · Call Activity · Transaction Sub-Process · Ad-Hoc Sub-Process · Event sub-processes
- Related: Activities taxonomy · Boundary events · Registering & versioning
- Design: ADR-023 — Sub-Process & Call Activity · ADR-028 — Transaction Sub-Process · ADR-035 — Ad-Hoc Sub-Process
- Full API:
go doc github.com/dr-dobermann/gobpm/pkg/model/activities