2018-05-04 18:24 GMT+03:00 Bruno Albuquerque <b...@bug-br.org.br>: > Here is an example that came up in the list that might help you: > https://play.golang.org/p/I8MS0DFgZ2 >
Thank you! This is exactly the code I looked for. However I should say this approach is not very much elegant because the select statement randomizes the channels first and then one must fight that randomness with a separate procedure to drain the hi channel. > That being said, It looks like you are over engineering. If I really > understand what you want to accomplish, wouldn't this help? > > https://github.com/brunoga/workerpool > > You can call Stop()/Start() to stop and resume the workers. > I do not want to stop the workers or otherwise I should deal with the items which remain in the queue in case the application should terminate immediately. It's much simpler for me to wait until the already queued work is done. > > On Fri, May 4, 2018 at 7:24 AM <bambys...@gmail.com> wrote: > >> Hi, >> >> I have a scenario which I haven't found a way to implement with the Go >> channels and select statement while it's no problem to do it with the >> select()/poll() functions. The scenario is as follows. >> >> Let me use a Go-like pseudo-code to demonstrate the idea. There is a >> source of a work items which are processed by several goroutines. Here is >> the source procedure: >> >> work_ch := make(chan *WorkItem) >> >> for { >> work_ch <- NewWorkItem() >> } >> >> And here is the worker thread: >> >> for { >> wi := <-work_ch >> self.do_the_work(wi) >> } >> >> Now I need to suspend the work. I stop supplying the work items and want >> to make sure the worker goroutines are done with the work. The source >> procedure becomes something like this: >> >> for { >> if suspend_requested { >> for _, worker := range workers { >> worker.idle_request <- true >> } >> for _, worker := range workers { >> <-worker.idle_response >> } >> report_suspend_is_success() >> wait_until_unsuspended() >> } >> work_ch <- NewWorkItem() >> } >> >> And I want to modify the worker thread like this: >> >> for { >> select { >> case wi := <- work_ch: >> self.do_the_work(wi) >> case <-self.idle_request: >> self.idle_response <- true >> } >> } >> >> However this last snippet of code does not work because the cases within >> the select statement are randomly chosen when both channels are ready so I >> have no guarantee that the first case is executed first. >> >> Talking about the select() or poll() functions from the C library which >> evidently were an inspiration for the Go select statement, there is no >> problem with the described approach. It's because the select() function >> returns a complete information about the state of all the monitored >> descriptors and allows the programmer to decide what he wants to read or >> write and in which order, based on readiness of every descriptor. >> >> I think it would be a great idea to have some function similar to >> select()/poll() but working with the Go channels. >> >> -- >> 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+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/d/optout. >> > -- Andriy Pylypenko Development Lead Sippy Software, Inc. Internet Telephony (VoIP) Experts T/F: +1-646-651-1110 Web: http://www.sippysoft.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+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.