github.com/lingyao2333/mo-zero@v1.4.1/core/executors/bulkexecutor.go (about) 1 package executors 2 3 import "time" 4 5 const defaultBulkTasks = 1000 6 7 type ( 8 // BulkOption defines the method to customize a BulkExecutor. 9 BulkOption func(options *bulkOptions) 10 11 // A BulkExecutor is an executor that can execute tasks on either requirement meets: 12 // 1. up to given size of tasks 13 // 2. flush interval time elapsed 14 BulkExecutor struct { 15 executor *PeriodicalExecutor 16 container *bulkContainer 17 } 18 19 bulkOptions struct { 20 cachedTasks int 21 flushInterval time.Duration 22 } 23 ) 24 25 // NewBulkExecutor returns a BulkExecutor. 26 func NewBulkExecutor(execute Execute, opts ...BulkOption) *BulkExecutor { 27 options := newBulkOptions() 28 for _, opt := range opts { 29 opt(&options) 30 } 31 32 container := &bulkContainer{ 33 execute: execute, 34 maxTasks: options.cachedTasks, 35 } 36 executor := &BulkExecutor{ 37 executor: NewPeriodicalExecutor(options.flushInterval, container), 38 container: container, 39 } 40 41 return executor 42 } 43 44 // Add adds task into be. 45 func (be *BulkExecutor) Add(task interface{}) error { 46 be.executor.Add(task) 47 return nil 48 } 49 50 // Flush forces be to flush and execute tasks. 51 func (be *BulkExecutor) Flush() { 52 be.executor.Flush() 53 } 54 55 // Wait waits be to done with the task execution. 56 func (be *BulkExecutor) Wait() { 57 be.executor.Wait() 58 } 59 60 // WithBulkTasks customizes a BulkExecutor with given tasks limit. 61 func WithBulkTasks(tasks int) BulkOption { 62 return func(options *bulkOptions) { 63 options.cachedTasks = tasks 64 } 65 } 66 67 // WithBulkInterval customizes a BulkExecutor with given flush interval. 68 func WithBulkInterval(duration time.Duration) BulkOption { 69 return func(options *bulkOptions) { 70 options.flushInterval = duration 71 } 72 } 73 74 func newBulkOptions() bulkOptions { 75 return bulkOptions{ 76 cachedTasks: defaultBulkTasks, 77 flushInterval: defaultFlushInterval, 78 } 79 } 80 81 type bulkContainer struct { 82 tasks []interface{} 83 execute Execute 84 maxTasks int 85 } 86 87 func (bc *bulkContainer) AddTask(task interface{}) bool { 88 bc.tasks = append(bc.tasks, task) 89 return len(bc.tasks) >= bc.maxTasks 90 } 91 92 func (bc *bulkContainer) Execute(tasks interface{}) { 93 vals := tasks.([]interface{}) 94 bc.execute(vals) 95 } 96 97 func (bc *bulkContainer) RemoveAll() interface{} { 98 tasks := bc.tasks 99 bc.tasks = nil 100 return tasks 101 }