Skip to content

Instantly share code, notes, and snippets.

@JalfResi
Created September 19, 2014 11:30
Show Gist options
  • Save JalfResi/32e6cf47df0fb68818c0 to your computer and use it in GitHub Desktop.
Save JalfResi/32e6cf47df0fb68818c0 to your computer and use it in GitHub Desktop.
Scaleable Channel Stack with workers
package main
import (
"log"
"sync"
)
// ***************************
type Worker chan struct{}
func (w Worker) DoWork() {
for {
select {
case _, ok := <-w:
if !ok {
log.Println("Dying gracefully")
return
}
default:
}
}
}
func (w Worker) DieGracefully() {
close(w)
}
// ***************************
type Stack struct {
sync.Mutex
stack []Worker
}
func (s *Stack) Inc(count int) []Worker {
var temp []Worker
for n := 0; n < count; n++ {
ch := make(Worker, 1)
temp = append(temp, ch)
}
s.Lock()
defer s.Unlock()
s.stack = append(s.stack, temp...)
return temp
}
func (s *Stack) Dec(count int) (r []Worker) {
s.Lock()
defer s.Unlock()
var o []Worker = make([]Worker, len(s.stack)-count)
copy(o, s.stack[:len(s.stack)-count])
var n []Worker = make([]Worker, count)
copy(n, s.stack[len(s.stack)-count:])
s.stack = o
return n
}
func (s *Stack) Len() int {
return len(s.stack)
}
// ***************************
func main() {
quit := make(chan bool)
stack := &Stack{}
// Hook up workers here...
for _, worker := range stack.Inc(10) {
go worker.DoWork()
}
log.Println(stack.Len())
// Send kill signal over this slice of chans
for _, worker := range stack.Dec(3) {
worker.DieGracefully()
}
log.Println(stack.Len())
<-quit
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment