forked from TrueCloudLab/frostfs-node
110 lines
3.1 KiB
Go
110 lines
3.1 KiB
Go
|
package object
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
|
||
|
"github.com/nspcc-dev/neofs-api-go/object"
|
||
|
)
|
||
|
|
||
|
type (
|
||
|
// requestHandler is an interface of Object service cross-request handler.
|
||
|
requestHandler interface {
|
||
|
// Handles request by parameter-bound logic.
|
||
|
handleRequest(context.Context, handleRequestParams) (interface{}, error)
|
||
|
}
|
||
|
|
||
|
handleRequestParams struct {
|
||
|
// Processing request.
|
||
|
request serviceRequest
|
||
|
|
||
|
// Processing request executor.
|
||
|
executor requestHandleExecutor
|
||
|
}
|
||
|
|
||
|
// coreRequestHandler is an implementation of requestHandler interface used in Object service production.
|
||
|
coreRequestHandler struct {
|
||
|
// Request preprocessor.
|
||
|
preProc requestPreProcessor
|
||
|
|
||
|
// Request postprocessor.
|
||
|
postProc requestPostProcessor
|
||
|
}
|
||
|
|
||
|
// requestHandleExecutor is an interface of universal Object operation executor.
|
||
|
requestHandleExecutor interface {
|
||
|
// Executes actions parameter-bound logic and returns execution result.
|
||
|
executeRequest(context.Context, serviceRequest) (interface{}, error)
|
||
|
}
|
||
|
)
|
||
|
|
||
|
var _ requestHandler = (*coreRequestHandler)(nil)
|
||
|
|
||
|
// requestHandler method implementation.
|
||
|
//
|
||
|
// If internal requestPreProcessor returns non-nil error for request argument, it returns.
|
||
|
// Otherwise, requestHandleExecutor argument performs actions. Received error is passed to requestPoistProcessor routine.
|
||
|
// Returned results of requestHandleExecutor are return.
|
||
|
func (s *coreRequestHandler) handleRequest(ctx context.Context, p handleRequestParams) (interface{}, error) {
|
||
|
if err := s.preProc.preProcess(ctx, p.request); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
res, err := p.executor.executeRequest(ctx, p.request)
|
||
|
|
||
|
go s.postProc.postProcess(ctx, p.request, err)
|
||
|
|
||
|
return res, err
|
||
|
}
|
||
|
|
||
|
// TODO: separate executors for each operation
|
||
|
// requestHandleExecutor method implementation.
|
||
|
func (s *objectService) executeRequest(ctx context.Context, req serviceRequest) (interface{}, error) {
|
||
|
switch r := req.(type) {
|
||
|
case *object.SearchRequest:
|
||
|
return s.objSearcher.searchObjects(ctx, &transportRequest{
|
||
|
serviceRequest: r,
|
||
|
timeout: s.pSrch.Timeout,
|
||
|
})
|
||
|
case *putRequest:
|
||
|
addr, err := s.objStorer.putObject(ctx, r)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
resp := makePutResponse(*addr)
|
||
|
if err := s.respPreparer.prepareResponse(ctx, r.PutRequest, resp); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
return nil, r.srv.SendAndClose(resp)
|
||
|
case *object.DeleteRequest:
|
||
|
return nil, s.objRemover.delete(ctx, &transportRequest{
|
||
|
serviceRequest: r,
|
||
|
timeout: s.pDel.Timeout,
|
||
|
})
|
||
|
case *object.GetRequest:
|
||
|
return s.objRecv.getObject(ctx, &transportRequest{
|
||
|
serviceRequest: r,
|
||
|
timeout: s.pGet.Timeout,
|
||
|
})
|
||
|
case *object.HeadRequest:
|
||
|
return s.objRecv.getObject(ctx, &transportRequest{
|
||
|
serviceRequest: r,
|
||
|
timeout: s.pHead.Timeout,
|
||
|
})
|
||
|
case *GetRangeRequest:
|
||
|
return s.payloadRngRecv.getRangeData(ctx, &transportRequest{
|
||
|
serviceRequest: r,
|
||
|
timeout: s.pRng.Timeout,
|
||
|
})
|
||
|
case *object.GetRangeHashRequest:
|
||
|
return s.rngRecv.getRange(ctx, &transportRequest{
|
||
|
serviceRequest: r,
|
||
|
timeout: s.pRng.Timeout,
|
||
|
})
|
||
|
default:
|
||
|
panic(fmt.Sprintf(pmWrongRequestType, r))
|
||
|
}
|
||
|
}
|