%PDF- %PDF-
Direktori : /home/waritko/go/src/github.com/odeke-em/semalim/ |
Current File : //home/waritko/go/src/github.com/odeke-em/semalim/semalim.go |
// Copyright 2015 Emmanuel Odeke. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package semalim type ackType struct{} var sentinel = ackType{} type Job interface { Id() interface{} Do() (interface{}, error) } type Result interface { Err() error Id() interface{} Value() interface{} } type resultSt struct { err error id interface{} value interface{} } func (rs resultSt) Err() error { return rs.err } func (rs resultSt) Id() interface{} { return rs.id } func (rs resultSt) Value() interface{} { return rs.value } func Run(jobs chan Job, workerCount uint64) chan Result { results := make(chan Result) doneChan := make(chan ackType) slots := make(chan ackType, workerCount) slotWait := func() { <-slots } slotReady := func() { slots <- sentinel } jobDone := func() { doneChan <- sentinel } if workerCount < 1 { workerCount = 8 // TODO: Define a proper default } // Make free room for the workerCount for i := uint64(0); i < workerCount; i++ { slotReady() } doneCounterChan := make(chan ackType) go func() { defer close(doneCounterChan) for job := range jobs { if job != nil { doneCounterChan <- sentinel go func(j Job) { slotWait() result, err := j.Do() results <- resultSt{id: j.Id(), err: err, value: result} slotReady() jobDone() }(job) } } }() go func() { defer close(results) doneCount := uint64(0) for _ = range doneCounterChan { doneCount += 1 } // Then finally wait until: for i := uint64(0); i < doneCount; i++ { <-doneChan } }() return results }