Skip to content

A goroutine job dispatcher based on worker-pool pattern.

License

Notifications You must be signed in to change notification settings

YSZhuoyang/go-dispatcher

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

72 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

go-dispatcher

Build Coverage Status GoDoc

A worker-pool job dispatcher inspired by the Post: Handling 1 Million Requests per Minute with Go.

  • Barrier Synchronization: Easily run batches of jobs in sequence, for algorithms that involve running a set of independent tasks concurrently for a while, then all wait on a barrier, and repeat again.
  • Bulkhead: keep workers in different pools isolated thus one failing does not affect others.
  • Limit total number of goroutines to prevent it from draining out resources.

How it works

                ----------------
   job queue -> |  dispatcher  |
                |              |
                ----------------
                      | /|\
                      |  |
                     \|/ |
                  -----------
                  |  worker |
                  |   pool  |
                  -----------

A dispatcher internally maintains a worker pool and runs a job dispatching loop assigning jobs to workers available. It then waits for all Jobs dispatched to finish and cleanup everything.

Note: a dispatcher is not meant to be reused, Finalize() must be called at the end to terminate its job dispatching loop. This is to avoid goroutine leaks.

How to use

  1. Download and import package.

     go get -u github.com/YSZhuoyang/go-dispatcher/dispatcher
    
  2. Create a job dispatcher with a worker pool initialized with given size, and start listening to new jobs.

     disp, _ := dispatcher.NewDispatcher(1000)
    
  3. Dispatch jobs (dispatch() will block until at least one worker becomes available and takes the job).

     type myJob struct {
         // ...
     }
    
     func (job *myJob) Do() {
         // Do something ...
     }
    
     disp.Dispatch(&myJob{...})
    
  4. Wait until all jobs are done and terminate the task loop.

     disp.Finalize()