Hi
I have to produce some task to kafka parallely. So I want to implement a simple worker group pattern in go.
Does the below code decent enough to take it to production?
var workerCount = runtime.NumCPU()*7 + 1
func WorkerPattern() {
taskWg := &sync.WaitGroup{}
taskWg.Add(2)
autoCancelChan := make(chan string, workerCount*3) // *3, just to make enough room. workers will be slower anyways
go produceTaskOfType1ToChan(taskWg, autoCancelChan)
go produceTaskOfType2ToChan(taskWg, autoCancelChan)
// start workers to push autoCancel to kafka
workerWg := &sync.WaitGroup{}
go kafkaProducerWorkers(autoCancelChan, workerWg)
// wait to close autoCancelChan channel till all the task is written
taskWg.Wait()
close(autoCancelChan)
// wait till all workers finish their task
workerWg.Wait()
fmt.Println("Done!!!")
}
func produceTaskOfType1ToChan(wg *sync.WaitGroup, autoCancelChan chan string) {
defer wg.Done()
// can produce random number of task on autoCancelChan
autoCancelChan <- "task of type of 1"
}
func produceTaskOfType2ToChan(wg *sync.WaitGroup, autoCancelChan chan string) {
defer wg.Done()
// can produce random number of task on autoCancelChan
autoCancelChan <- "task of type of 2"
}
func kafkaProducerWorkers(autoCancelChan chan string, workerWg *sync.WaitGroup) {
workerWg.Add(workerCount)
for i := 0; i < workerCount; i++ {
go produceToKafka(autoCancelChan, workerWg)
}
}
func produceToKafka(autoCancelChan chan string, workerWg *sync.WaitGroup) {
defer workerWg.Done()
// for loop will terminate once autoCancelChan is closed
for autoCancel := range autoCancelChan {
KafkaClient.PublishToKafkaTopic(autoCancel)
}
}
Any improvement you can suggest to this code?
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CANFuhy8qBjooo_tB_gT0f%3DTE4DaOFqWL5SWwNghy%2BL-eV82KdA%40mail.gmail.com.
func produceTaskOfType2ToChan(wg *sync.WaitGroup, autoCancelChan chan string) { defer wg.Done()
autoCancelIds := getAutoCancelIdsFromSource2() for autoCancelId := range autoCancelIds { autoCancelChan <- autoCancelId } }
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CANFuhy_AOfx9Vpq67tbwUJQhgfCi6Wmnsfu%2BFJ1yS%3DyyBFptkQ%40mail.gmail.com.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/f840beee-748f-42b6-809f-4c7505208aee%40googlegroups.com.
To unsubscribe from this group and stop receiving emails from it, send an email to golan...@googlegroups.com.
On Dec 28, 2019, at 7:02 AM, Agniva De Sarker <agniva.qu...@gmail.com> wrote:
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/ecddafbc-eb73-45e1-8a5a-f738e88c6821%40googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAOyqgcW9ORpo4dcUe6HYk1VS8Jp6J0EDpWAUXG4dHuYoUtbV7w%40mail.gmail.com.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/ecddafbc-eb73-45e1-8a5a-f738e88c6821%40googlegroups.com.
go kafkaProducerWorkers(autoCancelChan, workerWg)
workerWg.Wait()
line to be called be called before the kafkaProducerWorkers() goruotine has started, in which case the WorkerPattern funtion will return without any work haveing been done. See https://play.golang.org/p/p2_A3lBW3Dc for a simuation of this case. The Sleep() on line 52 simulates the slow starting goroutine. I agree. I meant that worker pools are especially useful when you can do cpu affinity - doesn’t apply to Go.
I think Go probably needs some idea of “capping” for cpu based workloads. You can cap in the local N CPUs
, but in a larger app that has multiple parallel processing points you can easy create too many routines and then you are paying overhead switching costs for no reason.
Which switching cost are you referring to? The switching cost between goroutines? This is minimal, as it takes places within a single thread. Or are you referring to cache invalidation issues? Or something else?
On Dec 30, 2019, at 9:11 AM, Jesper Louis Andersen <jesper.lou...@gmail.com> wrote:
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAGrdgiVje8SyiNZG-5JE8gE-%3DYOyDjdvVn-uyy95P3zzepc3wA%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/BA8435BE-3D84-446D-8C82-66A728A3F9AE%40ix.netcom.com.
Here is a simple test that demonstrates the dynamics https://play.golang.org/p/6SZcxCEAfFp (cannot run in playground)Notice that the call that uses an over allocated number of routines takes 5x longer wall time than the properly sized one - this is due to scheduling and contention on the underlying structures. So blindly creating go routines does not achieve optimum performance for many workloads (even when the number of OS threads is capped).rengels@rengels:~/gotest$ go run main_bench.go2.261805812s1.311269725s6.341378965s
-----Original Message-----
From: Robert Engels
Sent: Dec 30, 2019 3:21 PM
To: Robert Engels , Jesper Louis Andersen
Cc: Brian Candler , golang-nuts
Subject: Re: [go-nuts] Simple worker pool in golnag
Also, if running on a machine with a low cpu count (gomaxprocs) you probably need to increase the 'total' multiplier (mine was 12).
-----Original Message-----
From: Robert Engels
Sent: Dec 30, 2019 3:14 PM
To: Robert Engels , Jesper Louis Andersen
Cc: Brian Candler , golang-nuts
Subject: Re: [go-nuts] Simple worker pool in golnag
Here is a simple test that demonstrates the dynamics https://play.golang.org/p/6SZcxCEAfFp (cannot run in playground)Notice that the call that uses an over allocated number of routines takes 5x longer wall time than the properly sized one - this is due to scheduling and contention on the underlying structures. So blindly creating go routines does not achieve optimum performance for many workloads (even when the number of OS threads is capped).
rengels@rengels:~/gotest$ go run main_bench.go2.261805812s1.311269725s6.341378965s
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/408047985.1927.1577740873451%40wamui-lola.atl.sa.earthlink.net.
-----Original Message-----
From: Jesper Louis Andersen
Sent: Dec 30, 2019 3:41 PM
To: Robert Engels
Cc: Brian Candler , golang-nuts
Subject: Re: [go-nuts] Simple worker pool in golnag
On Mon, Dec 30, 2019 at 10:14 PM Robert Engels <ren...@ix.netcom.com> wrote:
Here is a simple test that demonstrates the dynamics https://play.golang.org/p/6SZcxCEAfFp (cannot run in playground)Notice that the call that uses an over allocated number of routines takes 5x longer wall time than the properly sized one - this is due to scheduling and contention on the underlying structures. So blindly creating go routines does not achieve optimum performance for many workloads (even when the number of OS threads is capped).rengels@rengels:~/gotest$ go run main_bench.go2.261805812s1.311269725s6.341378965s
Yes, this is unsurprising since the problem in the program is parallel.In a typical concurrent problem, most work is sitting and waiting for some event to happen and those events are usually measured in several milliseconds. For those problems, the switching cost is very low given the other benefits you gain. The key property there is rarely about speed, but about description of the problem to the machine.Go definitely leans toward concurrent problems. If you want to target parallel problems, you have other options which are better, depending on factors of distribution, GPU availability, etc.
--J.