Last active
May 14, 2020 17:57
-
-
Save jhidajat/61b7247d72f633d3b88f3a69cc91aaa5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func ProcessNode(node, spec) { | |
... | |
return ContentNodeWithDisplay{...} | |
} | |
type ProcessArgs { | |
node *ContentNode | |
spec ProcessNodeSpec | |
} | |
func Workers(task func(ProcessArgs), completionCallback func(), workerCount int) chan ProcessArgs { | |
arguments := make(chan ProcessArgs) | |
completedCounter := make(chan bool) | |
for i:=0; i<workerCount; i++ { | |
go func() { | |
for { | |
arg, success := <-arguments | |
if !ok { | |
completedCounter <- true | |
return | |
} | |
task(arg.node, arg.spec) | |
} | |
}() | |
} | |
// Create annother go-routine dedicated to keep track of completed processNode() go-routines | |
go func() { | |
for i:=0; i<workerCount; i++ { | |
<-completedCounter // blocking | |
} | |
// executed once there is no more blocking go-routine in the counter channel | |
// (i.e. all go-routines are completed) | |
completionCallback() | |
}() | |
return arguments // so that arguments can be exposed to processNodes | |
} | |
func processNodes(nodes, spec) { | |
validNodes := make([]*ContentNode, 0, len(nodes)) | |
for _, node := range nodes { | |
if node != nil { | |
validNodes = append(validNodes, node) | |
} | |
} | |
// only one message is pushed and pulled. Intention is | |
// to block main go-routine from exiting before completion | |
mainCanExit := make(chan bool) | |
workers := Workers( | |
// task invoked by go-routine | |
func(args ProcessArgs) { | |
ProcessNode(args.node, args.spec) | |
}, | |
// completion callback | |
func() { | |
mainCanExit<-true | |
}) | |
for _, node := range(validNodes) { | |
workers <- ProcessArgs(node, spec) | |
} | |
// close channel and processNodes() can finally exit | |
close(workers) | |
<-mainCanExit // blocking | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment