@@ -40,6 +40,10 @@ type ActionGraph struct {
4040 Outputs map [OutputId ]OutputDefinition `yaml:"outputs" json:"outputs" bson:"outputs"`
4141
4242 Entry string
43+
44+ // ConcurrencyLocks maps node ID → *sync.Mutex. Used to serialize concurrent
45+ // calls to a node's ExecuteImpl when the node's _disable_concurrency input is true.
46+ ConcurrencyLocks * sync.Map `yaml:"-" json:"-"`
4347}
4448
4549func (ag * ActionGraph ) AddNode (nodeId string , node NodeBaseInterface ) {
@@ -78,7 +82,8 @@ func (ag *ActionGraph) GetEntry() (NodeEntryInterface, error) {
7882
7983func NewActionGraph () ActionGraph {
8084 return ActionGraph {
81- Nodes : make (map [string ]NodeBaseInterface ),
85+ Nodes : make (map [string ]NodeBaseInterface ),
86+ ConcurrencyLocks : & sync.Map {},
8287 }
8388}
8489
@@ -245,10 +250,11 @@ func NewExecutionState(
245250 ctx , cancel := context .WithCancel (ctx )
246251
247252 return & ExecutionState {
248- Graph : graph ,
249- Hierarchy : make ([]NodeBaseInterface , 0 ),
250- ContextStackLock : & sync.RWMutex {},
251- OutputCacheLock : & sync.RWMutex {},
253+ Graph : graph ,
254+ Hierarchy : make ([]NodeBaseInterface , 0 ),
255+ ContextStackLock : & sync.RWMutex {},
256+ OutputCacheLock : & sync.RWMutex {},
257+ PendingConcurrencyLocks : & sync.Map {},
252258
253259 IsDebugSession : debugCb != nil ,
254260 DebugCallback : debugCb ,
@@ -815,6 +821,15 @@ func LoadInputValues(node NodeBaseInterface, nodeI map[string]any, validate bool
815821
816822 subInputs := map [string ][]subInput {}
817823
824+ // _disable_concurrency is not a regular input, its stored directly on
825+ // the node instance so we pull it out before processing the rest.
826+ if v , ok := inputValues ["_disable_concurrency" ]; ok {
827+ if b , ok := v .(bool ); ok && b {
828+ node .SetDisableConcurrency (true )
829+ }
830+ delete (inputValues , "_disable_concurrency" )
831+ }
832+
818833 for portId , inputValue := range inputValues {
819834 groupInputId , portIndex , isIndexPort := IsValidIndexPortId (portId )
820835 if isIndexPort {
0 commit comments