User Tools

Site Tools


Spooler template

spooler.go
/*
 * Author, Copyright: Oleg Borodin <onborodin@gmail.com>
 */
 
package main
 
import (
	"fmt"
	"time"
	"math/rand"
)
 
const (
	maxThreads = 5
)
 
 
type Spool struct {
	Signals chan string
}
 
func (this Spool) Push(tag string, message string) {
	fmt.Println("push:", tag) // Dummy
}
 
func (this Spool) Pull() {
	fmt.Println("pull") // Dummy
}
 
func (this Spool) Loop() {
	var threads int = 0
	var generation int = 0 // For easy id presentation
 
	for {
		list := []int{ 1, 2, 3, 4, 5, 6, 7 } // list := Pull() imitation
		for _, id := range list {
 
			fmt.Printf("start runner for %d\n", id + 10 * generation)  
			go this.Runner(id + 10 * generation)
			threads++
 
			if threads < maxThreads {
				continue
			}
 
			select {
				case msg := <-this.Signals:
					threads--
					fmt.Println("received:", msg)
				case <-time.After(time.Second * 1):
					fmt.Println("timeout")
			}
		}
		generation++
	}
}
 
func (this Spool) Runner(id int) {
	rand.Seed(time.Now().UnixNano())
	n := rand.Intn(5) 
    time.Sleep(time.Duration(n)*time.Second)
	this.Signals <- fmt.Sprintf("job %d is done", id)
}
 
func New() *Spool {
	signals := make(chan string, 100)
	return &Spool{
		Signals: signals,
	}
}
 
func main() {
	spool := New()
	spool.Push("tagA", "messageA")
	spool.Loop()
}

Output

$ go run spooler.go
push: tagA
start runner for 1
start runner for 2
start runner for 3
start runner for 4
start runner for 5
timeout
start runner for 6
received: job 6 is done
start runner for 7
received: job 1 is done
start runner for 11
received: job 4 is done
start runner for 12
received: job 5 is done
start runner for 13
received: job 3 is done
start runner for 14
received: job 2 is done
start runner for 15
received: job 7 is done
start runner for 16
received: job 14 is done
start runner for 17
received: job 12 is done
start runner for 21
received: job 11 is done
start runner for 22
received: job 17 is done
start runner for 23
received: job 13 is done
start runner for 24
timeout
start runner for 25
received: job 15 is done
start runner for 26
received: job 16 is done
start runner for 27
received: job 21 is done
start runner for 31
timeout
start runner for 32
received: job 25 is done
start runner for 33
received: job 22 is done
start runner for 34
received: job 32 is done
start runner for 35
received: job 24 is done
start runner for 36
received: job 36 is done
start runner for 37
received: job 23 is done
start runner for 41
^Csignal: interrupt