I implemented a weighted fair queue using a naive approach which is giving different amount of attempts according to weights to access upstreams. However, when calls of fetch() come very fast, our internal sync constructs are not ready(when *select*) and many attempts are simply wasted. It seems that Go's scheduler steps in, therefore the results of many scenarios are not always predictable.
The involvement of Go's scheduler seems unavoidable. So is it innately unfit to implement WFQ in this way? One solution is to sleep in between calls of fetch() to simulate a constraint bandwidth which gives the scheduler leeway to synchronize, but this brings up another question of how long it should sleep. An alternative is instead of trying to access multiple queues in one process, use as many processes as the weight of one queue to serve the queue in question. Or can we tune the scheduler to what we want? What's the suggestion for this sort of problem? Code below: func Test_WFQ_DoNotWork(t *testing.T) { msgNum := 3600 // upstreams run at the same pace c1 := make(chan int, msgNum) c2 := make(chan int, msgNum) go func() { for i := 0; i < msgNum; i++ { c1 <- i c2 <- i } }() //weights 1:2 queueNames := []string{ "c1", "c2", "c2"} errEmpty := errors.New("msg N/A") fetch := func(c <-chan int) (int, error) { select { case i :=<- c: return i, nil default: return 0, errEmpty } } countC1, countC2 := 0, 0 for i := 0; i < msgNum; i++ { idx := i % len(queueNames) if queueNames[idx] == "c1" { _, err := fetch(c1) if err == nil { countC1++ } } else { _, err := fetch(c2) if err == nil { countC2++ } } } // The output is not always expected 1200:24000 fmt.Printf("countC1:%d, countC2:%d", countC1, countC2) } -- 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.