github.com/kaydxh/golang@v0.0.131/pkg/scheduler/dispatcher.go (about) 1 /* 2 *Copyright (c) 2022, kaydxh 3 * 4 *Permission is hereby granted, free of charge, to any person obtaining a copy 5 *of this software and associated documentation files (the "Software"), to deal 6 *in the Software without restriction, including without limitation the rights 7 *to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 *copies of the Software, and to permit persons to whom the Software is 9 *furnished to do so, subject to the following conditions: 10 * 11 *The above copyright notice and this permission notice shall be included in all 12 *copies or substantial portions of the Software. 13 * 14 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 *SOFTWARE. 21 */ 22 package scheduler 23 24 import ( 25 "context" 26 "fmt" 27 "sync" 28 29 "github.com/kaydxh/golang/pkg/scheduler/task" 30 task_ "github.com/kaydxh/golang/pkg/scheduler/task" 31 ) 32 33 type Dispatcher struct { 34 // tasks *sync.Map 35 workersChCh chan chan *task.Task 36 taskQueCh chan *task.Task 37 workers []*Worker 38 burst int 39 stopCh chan struct{} 40 } 41 42 func NewDispatcher(burst int) *Dispatcher { 43 d := &Dispatcher{ 44 workersChCh: make(chan chan *task.Task, burst), 45 taskQueCh: make(chan *task.Task, 100), 46 burst: burst, 47 stopCh: make(chan struct{}), 48 } 49 go d.run() 50 return d 51 } 52 53 func (d *Dispatcher) run() { 54 for i := 0; i < d.burst; i++ { 55 worker := NewWorker(i, d.workersChCh) 56 go worker.Process(context.Background()) 57 d.workers = append(d.workers, worker) 58 59 go d.dispatch() 60 } 61 } 62 63 func (d *Dispatcher) dispatch() { 64 65 for { 66 select { 67 case task := <-d.taskQueCh: 68 taskCh := <-d.workersChCh 69 taskCh <- task 70 71 case <-d.stopCh: 72 d.stopWokrs() 73 return 74 } 75 76 } 77 } 78 79 func (d *Dispatcher) stopWokrs() { 80 wg := new(sync.WaitGroup) 81 wg.Add(len(d.workers)) 82 for _, v := range d.workers { 83 go func(w *Worker, wg *sync.WaitGroup) { 84 defer wg.Done() 85 if w.working { 86 w.Stop() 87 } 88 }(v, wg) 89 90 } 91 92 wg.Wait() 93 } 94 95 func (d *Dispatcher) AddTask(task *task_.Task) error { 96 err := task_.Validate(task) 97 if err != nil { 98 return err 99 } 100 d.taskQueCh <- task 101 fmt.Println("add task") 102 103 return nil 104 } 105 106 func (d *Dispatcher) Stop() { 107 close(d.stopCh) 108 }