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.

Reply via email to