github.com/matrixorigin/matrixone@v1.2.0/pkg/vm/engine/tae/logstore/driver/logservicedriver/append.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 logservicedriver 16 17 import ( 18 "time" 19 20 "github.com/matrixorigin/matrixone/pkg/common/moerr" 21 "github.com/matrixorigin/matrixone/pkg/logutil" 22 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/logstore/driver/entry" 23 ) 24 25 var ErrTooMuchPenddings = moerr.NewInternalErrorNoCtx("too much penddings") 26 27 func (d *LogServiceDriver) Append(e *entry.Entry) error { 28 d.driverLsnMu.Lock() 29 e.Lsn = d.allocateDriverLsn() 30 _, err := d.preAppendLoop.Enqueue(e) 31 if err != nil { 32 panic(err) 33 } 34 d.driverLsnMu.Unlock() 35 return nil 36 } 37 38 func (d *LogServiceDriver) getAppender() *driverAppender { 39 if int(d.appendable.entry.payloadSize) > d.config.RecordSize { 40 d.appendAppender() 41 } 42 return d.appendable 43 } 44 45 func (d *LogServiceDriver) appendAppender() { 46 d.appendtimes++ 47 d.onAppendQueue(d.appendable) 48 d.appendedQueue <- d.appendable 49 d.appendable = newDriverAppender() 50 } 51 52 func (d *LogServiceDriver) onPreAppend(items ...any) { 53 for _, item := range items { 54 e := item.(*entry.Entry) 55 appender := d.getAppender() 56 appender.appendEntry(e) 57 } 58 d.appendAppender() 59 } 60 61 func (d *LogServiceDriver) onAppendQueue(appender *driverAppender) { 62 appender.client, appender.appendlsn = d.getClient() 63 appender.entry.SetAppended(d.getSynced()) 64 appender.contextDuration = d.config.NewClientDuration 65 appender.wg.Add(1) 66 d.appendPool.Submit(func() { 67 appender.append(d.config.RetryTimeout, d.config.ClientAppendDuration) 68 }) 69 } 70 71 func (d *LogServiceDriver) getClient() (client *clientWithRecord, lsn uint64) { 72 lsn, err := d.retryAllocateAppendLsnWithTimeout(uint64(d.config.ClientMaxCount), time.Second) 73 if err != nil { 74 panic(err) 75 } 76 client, err = d.clientPool.Get() 77 if err != nil { 78 logutil.Infof("LogService Driver: retry append err is %v", err) 79 err = RetryWithTimeout(d.config.RetryTimeout, func() (shouldReturn bool) { 80 client, err = d.clientPool.Get() 81 return err == nil 82 }) 83 if err != nil { 84 panic(err) 85 } 86 } 87 return 88 } 89 90 func (d *LogServiceDriver) onAppendedQueue(items []any, q chan any) { 91 appenders := make([]*driverAppender, 0) 92 93 for _, item := range items { 94 appender := item.(*driverAppender) 95 appender.waitDone() 96 d.clientPool.Put(appender.client) 97 appender.freeEntries() 98 appenders = append(appenders, appender) 99 } 100 q <- appenders 101 } 102 103 func (d *LogServiceDriver) onPostAppendQueue(items []any, _ chan any) { 104 appended := make([]uint64, 0) 105 for _, v := range items { 106 batch := v.([]*driverAppender) 107 for _, appender := range batch { 108 d.logAppend(appender) 109 appended = append(appended, appender.appendlsn) 110 } 111 } 112 d.onAppend(appended) 113 }