github.com/matrixorigin/matrixone@v1.2.0/pkg/vm/engine/tae/db/scheduler.go (about) 1 // Copyright 2021 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package db 16 17 import ( 18 "fmt" 19 20 "github.com/matrixorigin/matrixone/pkg/common/moerr" 21 22 "github.com/matrixorigin/matrixone/pkg/logutil" 23 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common" 24 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/tasks" 25 ) 26 27 var ( 28 ErrTaskDuplicated = moerr.NewInternalErrorNoCtx("tae task: duplicated task found") 29 ErrTaskNotFound = moerr.NewInternalErrorNoCtx("tae task: task not found") 30 ) 31 32 type taskScheduler struct { 33 *tasks.BaseScheduler 34 db *DB 35 } 36 37 func newTaskScheduler(db *DB, asyncWorkers int, ioWorkers int) *taskScheduler { 38 if asyncWorkers < 0 { 39 panic(fmt.Sprintf("bad param: %d txn workers", asyncWorkers)) 40 } 41 if ioWorkers < 0 { 42 panic(fmt.Sprintf("bad param: %d io workers", ioWorkers)) 43 } 44 s := &taskScheduler{ 45 BaseScheduler: tasks.NewBaseScheduler(db.Opts.Ctx, "taskScheduler"), 46 db: db, 47 } 48 jobDispatcher := newAsyncJobDispatcher() 49 jobHandler := tasks.NewPoolHandler(db.Opts.Ctx, asyncWorkers) 50 jobHandler.Start() 51 jobDispatcher.RegisterHandler(tasks.DataCompactionTask, jobHandler) 52 // jobDispatcher.RegisterHandler(tasks.GCTask, jobHandler) 53 gcHandler := tasks.NewSingleWorkerHandler(db.Opts.Ctx, "gc") 54 gcHandler.Start() 55 jobDispatcher.RegisterHandler(tasks.GCTask, gcHandler) 56 57 ckpDispatcher := tasks.NewBaseScopedDispatcher(tasks.DefaultScopeSharder) 58 for i := 0; i < 4; i++ { 59 handler := tasks.NewSingleWorkerHandler(db.Opts.Ctx, fmt.Sprintf("[ckpworker-%d]", i)) 60 ckpDispatcher.AddHandle(handler) 61 handler.Start() 62 } 63 64 ioDispatcher := tasks.NewBaseScopedDispatcher(nil) 65 for i := 0; i < ioWorkers; i++ { 66 handler := tasks.NewSingleWorkerHandler(db.Opts.Ctx, fmt.Sprintf("[ioworker-%d]", i)) 67 ioDispatcher.AddHandle(handler) 68 handler.Start() 69 } 70 71 s.RegisterDispatcher(tasks.GCTask, jobDispatcher) 72 s.RegisterDispatcher(tasks.DataCompactionTask, jobDispatcher) 73 s.RegisterDispatcher(tasks.IOTask, ioDispatcher) 74 s.RegisterDispatcher(tasks.CheckpointTask, ckpDispatcher) 75 s.Start() 76 return s 77 } 78 79 func (s *taskScheduler) Stop() { 80 s.BaseScheduler.Stop() 81 logutil.Info("TaskScheduler Stopped") 82 } 83 84 func (s *taskScheduler) ScheduleTxnTask( 85 ctx *tasks.Context, 86 taskType tasks.TaskType, 87 factory tasks.TxnTaskFactory) (task tasks.Task, err error) { 88 task = NewScheduledTxnTask(ctx, s.db, taskType, nil, factory) 89 err = s.Schedule(task) 90 return 91 } 92 93 func (s *taskScheduler) ScheduleMultiScopedTxnTask( 94 ctx *tasks.Context, 95 taskType tasks.TaskType, 96 scopes []common.ID, 97 factory tasks.TxnTaskFactory) (task tasks.Task, err error) { 98 task = NewScheduledTxnTask(ctx, s.db, taskType, scopes, factory) 99 err = s.Schedule(task) 100 return 101 } 102 103 func (s *taskScheduler) CheckAsyncScopes(scopes []common.ID) (err error) { 104 dispatcher := s.Dispatchers[tasks.DataCompactionTask].(*asyncJobDispatcher) 105 dispatcher.Lock() 106 defer dispatcher.Unlock() 107 return dispatcher.checkConflictLocked(scopes) 108 } 109 110 func (s *taskScheduler) ScheduleMultiScopedFn( 111 ctx *tasks.Context, 112 taskType tasks.TaskType, 113 scopes []common.ID, 114 fn tasks.FuncT) (task tasks.Task, err error) { 115 task = tasks.NewMultiScopedFnTask(ctx, taskType, scopes, fn) 116 err = s.Schedule(task) 117 return 118 } 119 120 func (s *taskScheduler) GetPenddingLSNCnt() uint64 { 121 return s.db.Wal.GetPenddingCnt() 122 } 123 124 func (s *taskScheduler) GetCheckpointedLSN() uint64 { 125 return s.db.Wal.GetCheckpointed() 126 } 127 128 func (s *taskScheduler) ScheduleFn(ctx *tasks.Context, taskType tasks.TaskType, fn func() error) (task tasks.Task, err error) { 129 task = tasks.NewFnTask(ctx, taskType, fn) 130 err = s.Schedule(task) 131 return 132 } 133 134 func (s *taskScheduler) ScheduleScopedFn(ctx *tasks.Context, taskType tasks.TaskType, scope *common.ID, fn func() error) (task tasks.Task, err error) { 135 task = tasks.NewScopedFnTask(ctx, taskType, scope, fn) 136 err = s.Schedule(task) 137 return 138 } 139 140 func (s *taskScheduler) Schedule(task tasks.Task) (err error) { 141 taskType := task.Type() 142 // if taskType == tasks.DataCompactionTask || taskType == tasks.GCTask { 143 if taskType == tasks.DataCompactionTask { 144 dispatcher := s.Dispatchers[task.Type()].(*asyncJobDispatcher) 145 return dispatcher.TryDispatch(task) 146 } 147 return s.BaseScheduler.Schedule(task) 148 }