Skip to content

Instantly share code, notes, and snippets.

@amimimor
Created March 9, 2016 07:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amimimor/0de6e1cba62fb0662a5b to your computer and use it in GitHub Desktop.
Save amimimor/0de6e1cba62fb0662a5b to your computer and use it in GitHub Desktop.
A template for an HTTP Request dispatcher and worker 'pool' (sharing channels with the Dispatcher)
package main
import (
// "flag"
"fmt"
"log"
"net/http"
"os"
"strings"
)
const (
numWorkers = 4
)
var c = make(chan *http.Request)
func main() {
flag.Parse()
quit := make(chan bool)
go produce("", c, quit)
d := &Dispatcher{quit: quit}
d.Init()
d.Dispatch()
<-quit
}
func produce(msg string, c chan *http.Request, quit chan bool) {
for i := 0; i <= numWorkers; i++ {
c <- cPost() // Expression to be sent can be any suitable value.
}
// this is actually useless since the producer should not call the quit channel
// but a 'global' counter that oversees that the number of jobs the workers received had
// been fulfilled plus a reasonable timeout for them to fetch
quit <- true
}
type Worker struct {
workers chan chan *http.Request
requests chan *http.Request
quit chan bool
}
type Dispatcher struct {
workers chan chan *http.Request
quit chan bool
}
func (d *Dispatcher) Init() {
d.workers = make(chan chan *http.Request, numWorkers)
}
func (d *Dispatcher) Dispatch() {
for i := 0; i <= numWorkers; i++ {
log.Printf("Dispatcher initalizing worker %d\n", i)
worker := &Worker{workers: d.workers, quit: d.quit}
worker.Init()
worker.Work()
}
go d.Listen()
}
func (d *Dispatcher) Listen() {
for {
select {
case job := <-c:
go func(j *http.Request) {
workerChan := <-d.workers
workerChan <- j
}(job)
}
}
}
func (w *Worker) Init() {
w.requests = make(chan *http.Request)
}
func (w *Worker) Work() {
go func() {
for {
w.workers <- w.requests
select {
case <-w.requests: // todo: assign the fetched chan value
fmt.Println("Doing the actual I/O request")
case <-w.quit:
return
// when done, I'm putting my channel back to the dispatcher so she can send me more jobs
}
}
}()
}
func cPost() *http.Request {
req, err := http.NewRequest(
"POST",
`/`,
strings.NewReader(`{"time":1111, "msg":"aaaaaa"}`),
)
if err != nil {
log.Fatalf("%v", err)
}
req.Header.Set(
"Content-Type",
"application/x-www-form-urlencoded; param=value",
)
return req
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment