Is there Go equivalent of Apple's GCD serial dispatch queue?
So far I have only found a solution that is a channel of functions.
work := make(chan func())
I would have a function receive from this channel and call the received functions. The functions must be executed in FIFO order.
Is there a better method or structure to do this in Go?
This shouldn't make a difference but I am looking to queue SQL queries to run in FIFO for this.
@OneOfOne, it was close but not quite.
I ended up making a Serial Dispatch Queue implementation in Go available here.
It is basically a go routine that blocks on a channel
of type func()
and runs the functions that are passed in order.
Implementation:
//Package serialqueue provides a serial queue for functions.
//Queue items are processed in First In First Out (FIFO) order.
package serialqueue
//New returns a new serial queue.
//Enqueue items like queueObj <- func() {doWork(data)}
func New() chan func() {
//create channel of type function
var queue = make(chan func())
//spawn go routine to read and run functions in the channel
go func() {
for true {
nextFunction := <-queue
nextFunction()
}
}()
return queue
}
Usage: (demonstrating writing to a string in the correct order)
//Package serialqueue provides provides tests for github.com/ansonl/serialqueue.
package serialqueue_test
import (
"testing"
"fmt"
"sync"
"github.com/ansonl/serialqueue"
)
func TestQueue(t *testing.T) {
//Create new serial queue
queue := serialqueue.New()
//Number of times to loop
var loops = 100
//Queue output will be added here
var queueOutput string
//WaitGroup for determining when queue output is finished
var wg sync.WaitGroup
//Create function to place in queue
var printTest = func(i int) {
queueOutput = fmt.Sprintf("%v%v",queueOutput, i)
wg.Done()
}
//Add functions to queue
var i int;
for i=0;i<loops;i++ {
wg.Add(1)
t:=i
queue <- func() {printTest(t)}
}
//Generate correct output
var correctOutput string
for i=0;i<loops;i++ {
correctOutput = fmt.Sprintf("%v%v", correctOutput, i)
}
//Wait until all functions in queue are done
wg.Wait()
//Compare queue output with correct output
if queueOutput != correctOutput {
t.Errorf("Serial Queue produced %v, want %v", queueOutput, correctOutput);
}
}
Hope this helps someone with the same issue!