github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/internal/bitask/memtable_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 22 "github.com/zuoyebang/bitalosdb/internal/base" 23 ) 24 25 type MemFlushTaskData struct { 26 Index int 27 NeedReport bool 28 } 29 30 type MemFlushTaskOptions struct { 31 Size int 32 DoFunc func(*MemFlushTaskData) 33 Logger base.Logger 34 TaskWg *sync.WaitGroup 35 } 36 37 type MemFlushTask struct { 38 taskWg *sync.WaitGroup 39 recvCh chan *MemFlushTaskData 40 closed atomic.Bool 41 logger base.Logger 42 doTaskFunc func(*MemFlushTaskData) 43 } 44 45 func NewMemFlushTask(opts *MemFlushTaskOptions) *MemFlushTask { 46 task := &MemFlushTask{ 47 recvCh: make(chan *MemFlushTaskData, opts.Size), 48 doTaskFunc: opts.DoFunc, 49 logger: opts.Logger, 50 taskWg: opts.TaskWg, 51 } 52 task.Run() 53 return task 54 } 55 56 func (t *MemFlushTask) Run() { 57 t.taskWg.Add(1) 58 go func() { 59 defer func() { 60 t.taskWg.Done() 61 t.logger.Infof("memtable flush task background exit...") 62 }() 63 64 do := func() bool { 65 defer func() { 66 if r := recover(); r != nil { 67 t.logger.Errorf("memtable flush task do panic err:%v stack:%s", r, string(debug.Stack())) 68 } 69 }() 70 71 task, ok := <-t.recvCh 72 if !ok || task == nil { 73 return true 74 } 75 76 t.doTaskFunc(task) 77 return false 78 } 79 80 var exit bool 81 for { 82 if exit = do(); exit { 83 break 84 } 85 } 86 }() 87 88 t.logger.Infof("memtable flush task background running...") 89 } 90 91 func (t *MemFlushTask) isClosed() bool { 92 return t.closed.Load() == true 93 } 94 95 func (t *MemFlushTask) Close() { 96 t.closed.Store(true) 97 t.recvCh <- nil 98 } 99 100 func (t *MemFlushTask) PushTask(task *MemFlushTaskData) { 101 if !t.isClosed() { 102 t.recvCh <- task 103 return 104 } 105 }