github.com/matrixorigin/matrixone@v1.2.0/pkg/vm/engine/tae/logtail/service/response.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 service
    16  
    17  import (
    18  	"fmt"
    19  	"math"
    20  	"sync"
    21  
    22  	"github.com/matrixorigin/matrixone/pkg/common/morpc"
    23  	"github.com/matrixorigin/matrixone/pkg/pb/logtail"
    24  )
    25  
    26  // LogtailResponse wraps logtail.LogtailResponse.
    27  type LogtailResponse struct {
    28  	logtail.LogtailResponse
    29  	closeCB func()
    30  }
    31  
    32  var _ morpc.Message = (*LogtailResponse)(nil)
    33  
    34  func (r *LogtailResponse) SetID(id uint64) {
    35  	r.ResponseId = id
    36  }
    37  
    38  func (r *LogtailResponse) GetID() uint64 {
    39  	return r.ResponseId
    40  }
    41  
    42  func (r *LogtailResponse) DebugString() string {
    43  	return ""
    44  }
    45  
    46  func (r *LogtailResponse) Size() int {
    47  	return r.ProtoSize()
    48  }
    49  
    50  // LogtailResponsePool acquires or releases LogtailResponse.
    51  type LogtailResponsePool interface {
    52  	// Acquire fetches item from pool.
    53  	Acquire() *LogtailResponse
    54  
    55  	// Release puts item back to pool.
    56  	Release(*LogtailResponse)
    57  }
    58  
    59  type responsePool struct {
    60  	pool *sync.Pool
    61  }
    62  
    63  func NewLogtailResponsePool() LogtailResponsePool {
    64  	return &responsePool{
    65  		pool: &sync.Pool{
    66  			New: func() any {
    67  				return &LogtailResponse{}
    68  			},
    69  		},
    70  	}
    71  }
    72  
    73  func (p *responsePool) Acquire() *LogtailResponse {
    74  	return p.pool.Get().(*LogtailResponse)
    75  }
    76  
    77  func (p *responsePool) Release(resp *LogtailResponse) {
    78  	if resp.closeCB != nil {
    79  		resp.closeCB()
    80  		resp.closeCB = nil
    81  	}
    82  	resp.Reset()
    83  	p.pool.Put(resp)
    84  }
    85  
    86  // LogtailResponseSegment wrps logtail.MessageSegment.
    87  type LogtailResponseSegment struct {
    88  	logtail.MessageSegment
    89  }
    90  
    91  var _ morpc.Message = (*LogtailResponseSegment)(nil)
    92  
    93  func (s *LogtailResponseSegment) SetID(id uint64) {
    94  	s.StreamID = id
    95  }
    96  
    97  func (s *LogtailResponseSegment) GetID() uint64 {
    98  	return s.StreamID
    99  }
   100  
   101  func (s *LogtailResponseSegment) DebugString() string {
   102  	return fmt.Sprintf(
   103  		"LogtailResponseSegment: StreamID=%d, MessageSize=%d, Sequence=%d, MaxSequence=%d",
   104  		s.GetStreamID(),
   105  		s.GetMessageSize(),
   106  		s.GetSequence(),
   107  		s.GetMaxSequence(),
   108  	)
   109  }
   110  
   111  func (s *LogtailResponseSegment) Size() int {
   112  	return s.ProtoSize()
   113  }
   114  
   115  // LogtailResponseSegmentPool acquires or releases LogtailResponseSegment.
   116  type LogtailResponseSegmentPool interface {
   117  	// Acquire fetches item from pool.
   118  	Acquire() *LogtailResponseSegment
   119  
   120  	// Release puts item back to pool.
   121  	Release(*LogtailResponseSegment)
   122  }
   123  
   124  // LogtailServerSegmentPool describes segment pool for logtail server.
   125  type LogtailServerSegmentPool interface {
   126  	LogtailResponseSegmentPool
   127  
   128  	// LeastEffectiveCapacity evaluates least effective payload size.
   129  	LeastEffectiveCapacity() int
   130  }
   131  
   132  type serverSegmentPool struct {
   133  	maxMessageSize int
   134  	pool           *sync.Pool
   135  }
   136  
   137  func NewLogtailServerSegmentPool(maxMessageSize int) LogtailServerSegmentPool {
   138  	return &serverSegmentPool{
   139  		maxMessageSize: maxMessageSize,
   140  		pool: &sync.Pool{
   141  			New: func() any {
   142  				seg := &LogtailResponseSegment{}
   143  				seg.Payload = make([]byte, maxMessageSize)
   144  				return seg
   145  			},
   146  		},
   147  	}
   148  }
   149  
   150  func (p *serverSegmentPool) Acquire() *LogtailResponseSegment {
   151  	return p.pool.Get().(*LogtailResponseSegment)
   152  }
   153  
   154  func (p *serverSegmentPool) Release(seg *LogtailResponseSegment) {
   155  	buf := seg.Payload
   156  	seg.Reset()
   157  	seg.Payload = buf[:cap(buf)]
   158  	p.pool.Put(seg)
   159  }
   160  
   161  func (p *serverSegmentPool) LeastEffectiveCapacity() int {
   162  	segment := p.Acquire()
   163  	defer p.Release(segment)
   164  
   165  	segment.StreamID = math.MaxUint64
   166  	segment.Sequence = math.MaxInt32
   167  	segment.MaxSequence = math.MaxInt32
   168  	segment.MessageSize = math.MaxInt32
   169  	maxHeaderSize := segment.ProtoSize() - p.maxMessageSize
   170  
   171  	// Take out reserved size, then effective capacity left.
   172  	return p.maxMessageSize - maxHeaderSize
   173  }