github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/internal/bitask/bitpage_task.go (about) 1 // Copyright 2021 The Bitalosdb author(hustxrb@163.com) and other contributors. 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 bitask 16 17 import ( 18 "runtime/debug" 19 "sync" 20 "sync/atomic" 21 "time" 22 23 "github.com/zuoyebang/bitalosdb/internal/base" 24 "github.com/zuoyebang/bitalosdb/internal/statemachine" 25 ) 26 27 const ( 28 BitpageEventFlush int = 1 + iota 29 BitpageEventSplit 30 BitpageEventFreePage 31 ) 32 33 func GetBitpageEventName(e int) string { 34 switch e { 35 case BitpageEventFlush: 36 return "flush" 37 case BitpageEventSplit: 38 return "split" 39 case BitpageEventFreePage: 40 return "freePage" 41 default: 42 return "" 43 } 44 } 45 46 type BitpageTaskData struct { 47 Index int 48 Event int 49 Pn uint32 50 Sentinel []byte 51 Pns []uint32 52 SendTime time.Time 53 WaitDuration time.Duration 54 } 55 56 type BitpageTaskOptions struct { 57 Size int 58 DbState *statemachine.DbStateMachine 59 DoFunc func(*BitpageTaskData) 60 Logger base.Logger 61 TaskWg *sync.WaitGroup 62 } 63 64 type BitpageTask struct { 65 taskWg *sync.WaitGroup 66 recvCh chan *BitpageTaskData 67 closed atomic.Bool 68 logger base.Logger 69 dbState *statemachine.DbStateMachine 70 doTaskFunc func(*BitpageTaskData) 71 } 72 73 func NewBitpageTask(opts *BitpageTaskOptions) *BitpageTask { 74 bpTask := &BitpageTask{ 75 recvCh: make(chan *BitpageTaskData, opts.Size), 76 dbState: opts.DbState, 77 doTaskFunc: opts.DoFunc, 78 logger: opts.Logger, 79 taskWg: opts.TaskWg, 80 } 81 bpTask.Run() 82 return bpTask 83 } 84 85 func (t *BitpageTask) Run() { 86 t.taskWg.Add(1) 87 go func() { 88 defer func() { 89 t.taskWg.Done() 90 t.logger.Infof("bitpage task background exit...") 91 }() 92 93 do := func() bool { 94 defer func() { 95 if r := recover(); r != nil { 96 t.logger.Errorf("bitpage task do panic err:%v stack:%s", r, string(debug.Stack())) 97 } 98 }() 99 100 task, ok := <-t.recvCh 101 if !ok || t.isClosed() || task == nil { 102 return true 103 } 104 105 task.WaitDuration = time.Since(task.SendTime) 106 t.dbState.WaitBitowerHighPriority(task.Index) 107 t.doTaskFunc(task) 108 return false 109 } 110 111 var exit bool 112 for { 113 if exit = do(); exit { 114 break 115 } 116 } 117 }() 118 119 t.logger.Infof("bitpage task background running...") 120 } 121 122 func (t *BitpageTask) isClosed() bool { 123 return t.closed.Load() == true 124 } 125 126 func (t *BitpageTask) Close() { 127 t.closed.Store(true) 128 t.recvCh <- nil 129 } 130 131 func (t *BitpageTask) PushTask(task *BitpageTaskData) { 132 if !t.isClosed() { 133 task.SendTime = time.Now() 134 t.recvCh <- task 135 } 136 }