github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/logstore/driver/logservicedriver/appender.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 "context" 19 "sync" 20 "time" 21 22 "github.com/matrixorigin/matrixone/pkg/logutil" 23 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/logstore/driver/entry" 24 ) 25 26 type driverAppender struct { 27 client *clientWithRecord 28 appendlsn uint64 29 logserviceLsn uint64 30 entry *recordEntry 31 contextDuration time.Duration 32 wg sync.WaitGroup //wait client 33 } 34 35 func newDriverAppender() *driverAppender { 36 return &driverAppender{ 37 entry: newRecordEntry(), 38 wg: sync.WaitGroup{}, 39 } 40 } 41 42 func (a *driverAppender) appendEntry(e *entry.Entry) { 43 a.entry.append(e) 44 } 45 46 func (a *driverAppender) append(retryTimout, appendTimeout time.Duration) { 47 size := a.entry.prepareRecord() 48 // if size > int(common.K)*20 { //todo 49 // panic(moerr.NewInternalError("record size %d, larger than max size 20K", size)) 50 // } 51 a.client.TryResize(size) 52 logutil.Debugf("Log Service Driver: append start prepare %p", a.client.record.Data) 53 record := a.client.record 54 copy(record.Payload(), a.entry.payload) 55 record.ResizePayload(size) 56 defer logSlowAppend()() 57 ctx, cancel := context.WithTimeout(context.Background(), appendTimeout) 58 logutil.Debugf("Log Service Driver: append start %p", a.client.record.Data) 59 lsn, err := a.client.c.Append(ctx, record) 60 if err != nil { 61 logutil.Errorf("append failed: %v", err) 62 } 63 cancel() 64 if err != nil { 65 err = RetryWithTimeout(retryTimout, func() (shouldReturn bool) { 66 ctx, cancel := context.WithTimeout(context.Background(), appendTimeout) 67 lsn, err = a.client.c.Append(ctx, record) 68 cancel() 69 if err != nil { 70 logutil.Errorf("append failed: %v", err) 71 } 72 return err == nil 73 }) 74 } 75 logutil.Debugf("Log Service Driver: append end %p", a.client.record.Data) 76 if err != nil { 77 logutil.Infof("size is %d", size) 78 panic(err) 79 } 80 a.logserviceLsn = lsn 81 a.wg.Done() 82 } 83 84 func (a *driverAppender) waitDone() { 85 a.wg.Wait() 86 } 87 88 func (a *driverAppender) freeEntries() { 89 for _, e := range a.entry.entries { 90 e.DoneWithErr(nil) 91 } 92 } 93 94 func logSlowAppend() func() { 95 const slowAppend = 1 * time.Second 96 start := time.Now() 97 return func() { 98 elapsed := time.Since(start) 99 if elapsed >= slowAppend { 100 logutil.Warnf("append to logservice took %s", elapsed) 101 } 102 } 103 }