ActionGroup
@MainActor
public final class ActionGroup<ContentType> : ActionPerformableCollection where ContentType : ContentTypeable
A group of actions which run concurrently, merging their results into one content value.
The child requests all run concurrently and receive the same input content. When they complete, a ActionResultsMerging object merges their results into a single content value. The group passes this content value and all of the group’s child results via a single ActionResult, and passes the merged value on through its output conduit.
Child failure behavior
Each child’s shouldEndParentTaskOnFailure flag controls what happens when that child fails:
true: The group immediately callscancelAll()on its remaining siblings, builds a group-levelActionResultcontaining all results collected up to that point plus the failing child’s failure result, and returnscancelled(partialResults:). Siblings that had not yet completed are cancelled.false: The group records the failure and lets all remaining siblings run to completion. Once every child has finished, the group builds a single group-levelActionResultwhoseoriginproperty includes child results for every task’s success or failure in declaration order, then returnscancelled(partialResults:). The merger is not called because not all children succeeded.
In both cases the caller receives one group ActionResult with a group(results:) origin. Use failedActions() on the partial results to inspect which children failed.
Note
You should not instantiate an ActionGroup directly. Instead you should create an ActionGroupConfiguration object to define it, and used in conjunction with performActions(configuration:content:).
Usage
Build a group by composing child ActionConfiguration objects inside an ActionGroupConfiguration. You can either assign this configuration to interactorsData and run it via its associated event type, or you can build these configurations within a state model and call performActions(configuration:content:) on its Destination.
// Each child configuration represents one parallel Interactor request.
let retrievalChildren: [any ActionConfiguring<InteractorType, ContentType>] = [
ActionConfiguration<InteractorType, ContentType, MyInteractor>(
interactorType: .myType,
action: .retrieveFile,
assistant: .basicAsync,
identifier: ActionIdentifier.retrieve),
ActionConfiguration<InteractorType, ContentType, MyInteractor>(
interactorType: .myType,
action: .retrieveFile,
assistant: .basicAsync,
identifier: ActionIdentifier.retrieve)
]
// The merger combines each child's result into a single ContentType value.
let retrievals = ActionGroupConfiguration<InteractorType, ContentType>(
actions: retrievalChildren,
merger: FileMerger(),
identifier: ActionIdentifier.retrievalGroup)
let result = await destination.performActions(configuration: retrievals, content: nil)
if case .success(let outputs) = result,
let groupResult = outputs.last(identifier: ActionIdentifier.retrievalGroup) {
// groupResult.content holds the merged value from all parallel children.
}
-
A unique identifier for this group instance.
Declaration
Swift
@MainActor public let id: UUID -
The child actions that run concurrently when this group is performed.
Declaration
Swift
@MainActor public var actions: [any ActionPerformable<ContentType>] -
An optional identifier used to tag this group’s
ActionResultin the sequence outputs.Declaration
Swift
@MainActor public let identifier: (any ActionIdentifying)? -
An optional conduit that receives the merged content value and passes it to the next step in the sequence.
Declaration
Swift
@MainActor public var outputConduit: (any ActionSequenceConduiting<ContentType>)? -
Always
nil; a group does not represent a single interactor action type.Declaration
Swift
@MainActor public var actionType: (any InteractorRequestActionTypeable)? { get } -
Controls how a failure in this group propagates to its parent sequence. When
true, siblings are cancelled immediately and the group fails fast. Whenfalse, all siblings run to completion and every result is collected before the group returns with a.failureResult. See the type-level documentation for the full behavioral description.Declaration
Swift
@MainActor public let shouldEndParentTaskOnFailure: Bool -
When
true, the merged result is recorded in the sequence outputs. Defaults totrue.Declaration
Swift
@MainActor public let shouldSaveResult: Bool -
Determines whether the results of this group’s children are saved in its origin when the group’s result is passed on
Declaration
Swift
@MainActor public let shouldSaveChildResults: Bool -
init(actions:merger: identifier: outputConduit: shouldEndParentTaskOnFailure: shouldSaveResult: shouldSaveChildResults: ) Creates a new action group.
Declaration
Swift
@MainActor public init(actions: [any ActionPerformable<ContentType>]? = nil, merger: any ActionResultsMerging<ContentType>, identifier: (any ActionIdentifying)? = nil, outputConduit: (any ActionSequenceConduiting<ContentType>)? = nil, shouldEndParentTaskOnFailure: Bool? = nil, shouldSaveResult: Bool? = nil, shouldSaveChildResults: Bool? = nil)Parameters
actionsThe child actions to run concurrently. Pass
nilto start with an empty group and add actions later viaadd(action:).mergerThe object that merges each child’s
ActionResultinto a singleContentTypevalue.identifierAn optional identifier attached to the group’s recorded
ActionResult.outputConduitAn optional conduit that forwards the merged content value to the next sequence step.
shouldEndParentTaskOnFailurePass
trueto cancel sibling actions and fail the sequence when any child fails. Defaults tofalse.shouldSaveResultPass
falseto skip recording the merged result in the sequence outputs. Defaults totrue. -
Appends an action to the group’s child action list.
Throws
ActionErrorif the action cannot be added.Declaration
Swift
@MainActor public func add(action: any ActionPerformable<ContentType>) throwsParameters
actionThe action to add.
-
perform(with:AsynchronoussequenceOutputs: ) Runs all child actions concurrently, merges their results, and returns the updated sequence outputs.
Each child action receives the same
contentvalue and the currentsequenceOutputs. When all children complete successfully, their individualActionResultvalues are merged into a singleContentTypeby the group’sActionResultsMergingobject. The group then appends oneActionResult(with originActionResponseSource/group(results:)) to the outputs and, if anoutputConduitis set, forwards the merged value to the next sequence step.Declaration
Swift
@MainActor public func perform(with content: ContentType?, sequenceOutputs: ActionCollectionResults<ContentType>) async -> Result<ActionCollectionResults<ContentType>, any Error>Parameters
contentThe input content passed to every child action.
sequenceOutputsThe accumulated results from all prior steps in the sequence.
Return Value
.successwith the updatedActionCollectionResultson success, or.failurewrapping anActionErrorif a child fails, the merger throws, or the task is cancelled.
View on GitHub