93 lines
2.2 KiB
Go
93 lines
2.2 KiB
Go
|
package container
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
|
||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/util"
|
||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/util/response"
|
||
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/container"
|
||
|
)
|
||
|
|
||
|
type (
|
||
|
TransportSplitter struct {
|
||
|
next Server
|
||
|
|
||
|
respSvc *response.Service
|
||
|
cnrAmount uint32
|
||
|
}
|
||
|
|
||
|
listStreamMsgSizeCtrl struct {
|
||
|
util.ServerStream
|
||
|
stream ListStream
|
||
|
respSvc *response.Service
|
||
|
cnrAmount uint32
|
||
|
}
|
||
|
)
|
||
|
|
||
|
func NewSplitterService(cnrAmount uint32, respSvc *response.Service, next Server) Server {
|
||
|
return &TransportSplitter{
|
||
|
next: next,
|
||
|
respSvc: respSvc,
|
||
|
cnrAmount: cnrAmount,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (s *TransportSplitter) Put(ctx context.Context, req *container.PutRequest) (*container.PutResponse, error) {
|
||
|
return s.next.Put(ctx, req)
|
||
|
}
|
||
|
|
||
|
func (s *TransportSplitter) Delete(ctx context.Context, req *container.DeleteRequest) (*container.DeleteResponse, error) {
|
||
|
return s.next.Delete(ctx, req)
|
||
|
}
|
||
|
|
||
|
func (s *TransportSplitter) Get(ctx context.Context, req *container.GetRequest) (*container.GetResponse, error) {
|
||
|
return s.next.Get(ctx, req)
|
||
|
}
|
||
|
|
||
|
func (s *TransportSplitter) List(ctx context.Context, req *container.ListRequest) (*container.ListResponse, error) {
|
||
|
return s.next.List(ctx, req)
|
||
|
}
|
||
|
|
||
|
func (s *TransportSplitter) ListStream(req *container.ListStreamRequest, stream ListStream) error {
|
||
|
return s.next.ListStream(req, &listStreamMsgSizeCtrl{
|
||
|
ServerStream: stream,
|
||
|
stream: stream,
|
||
|
respSvc: s.respSvc,
|
||
|
cnrAmount: s.cnrAmount,
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func (s *listStreamMsgSizeCtrl) Send(resp *container.ListStreamResponse) error {
|
||
|
s.respSvc.SetMeta(resp)
|
||
|
body := resp.GetBody()
|
||
|
ids := body.GetContainerIDs()
|
||
|
|
||
|
var newResp *container.ListStreamResponse
|
||
|
|
||
|
for {
|
||
|
if newResp == nil {
|
||
|
newResp = new(container.ListStreamResponse)
|
||
|
newResp.SetBody(body)
|
||
|
}
|
||
|
|
||
|
cut := min(s.cnrAmount, uint32(len(ids)))
|
||
|
|
||
|
body.SetContainerIDs(ids[:cut])
|
||
|
newResp.SetMetaHeader(resp.GetMetaHeader())
|
||
|
newResp.SetVerificationHeader(resp.GetVerificationHeader())
|
||
|
|
||
|
if err := s.stream.Send(newResp); err != nil {
|
||
|
return fmt.Errorf("TransportSplitter: %w", err)
|
||
|
}
|
||
|
|
||
|
ids = ids[cut:]
|
||
|
|
||
|
if len(ids) == 0 {
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|