Skip to content

Commit

Permalink
client: External statistic in containers
Browse files Browse the repository at this point in the history
Signed-off-by: Evgenii Baidakov <[email protected]>
  • Loading branch information
smallhive committed Jun 22, 2023
1 parent ba5c952 commit d5cea25
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 66 deletions.
101 changes: 80 additions & 21 deletions client/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"time"

v2container "github.com/nspcc-dev/neofs-api-go/v2/container"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
Expand All @@ -15,6 +16,7 @@ import (
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
"github.com/nspcc-dev/neofs-sdk-go/eacl"
"github.com/nspcc-dev/neofs-sdk-go/session"
"github.com/nspcc-dev/neofs-sdk-go/stat"
"github.com/nspcc-dev/neofs-sdk-go/user"
)

Expand Down Expand Up @@ -63,7 +65,12 @@ func (x *PrmContainerPut) WithinSession(s session.Container) {
//
// Return errors:
// - [ErrMissingSigner]
func (c *Client) ContainerPut(ctx context.Context, cont container.Container, prm PrmContainerPut) (cid.ID, error) {
func (c *Client) ContainerPut(ctx context.Context, cont container.Container, prm PrmContainerPut) (_ cid.ID, err error) {
ts := time.Now()
defer func() {
c.sendStatistic(stat.MethodContainerPut, time.Since(ts), err)
}()

signer, err := c.getSigner(prm.signer)
if err != nil {
return cid.ID{}, err
Expand All @@ -76,7 +83,8 @@ func (c *Client) ContainerPut(ctx context.Context, cont container.Container, prm
var sig neofscrypto.Signature
err = cont.CalculateSignature(&sig, signer)
if err != nil {
return cid.ID{}, fmt.Errorf("calculate container signature: %w", err)
err = fmt.Errorf("calculate container signature: %w", err)
return cid.ID{}, err
}

var sigv2 refs.Signature
Expand Down Expand Up @@ -136,6 +144,7 @@ func (c *Client) ContainerPut(ctx context.Context, cont container.Container, prm

// process call
if !cc.processCall() {
err = cc.err
return cid.ID{}, cc.err
}

Expand All @@ -156,9 +165,15 @@ type PrmContainerGet struct {
//
// Return errors:
// - [ErrMissingSigner]
func (c *Client) ContainerGet(ctx context.Context, id cid.ID, prm PrmContainerGet) (container.Container, error) {
func (c *Client) ContainerGet(ctx context.Context, id cid.ID, prm PrmContainerGet) (_ container.Container, err error) {
ts := time.Now()
defer func() {
c.sendStatistic(stat.MethodContainerGet, time.Since(ts), err)
}()

if c.prm.signer == nil {
return container.Container{}, ErrMissingSigner
err = ErrMissingSigner
return container.Container{}, err
}

var cidV2 refs.ContainerID
Expand Down Expand Up @@ -203,6 +218,7 @@ func (c *Client) ContainerGet(ctx context.Context, id cid.ID, prm PrmContainerGe

// process call
if !cc.processCall() {
err = cc.err
return container.Container{}, cc.err
}

Expand All @@ -223,9 +239,15 @@ type PrmContainerList struct {
//
// Return errors:
// - [ErrMissingSigner]
func (c *Client) ContainerList(ctx context.Context, ownerID user.ID, prm PrmContainerList) ([]cid.ID, error) {
func (c *Client) ContainerList(ctx context.Context, ownerID user.ID, prm PrmContainerList) (_ []cid.ID, err error) {
ts := time.Now()
defer func() {
c.sendStatistic(stat.MethodContainerList, time.Since(ts), err)
}()

if c.prm.signer == nil {
return nil, ErrMissingSigner
err = ErrMissingSigner
return nil, err
}

// form request body
Expand Down Expand Up @@ -269,6 +291,7 @@ func (c *Client) ContainerList(ctx context.Context, ownerID user.ID, prm PrmCont

// process call
if !cc.processCall() {
err = cc.err
return nil, cc.err
}

Expand Down Expand Up @@ -319,14 +342,20 @@ func (x *PrmContainerDelete) WithinSession(tok session.Container) {
// Return errors:
// - [ErrMissingSigner]
// - [neofscrypto.ErrIncorrectSigner]
func (c *Client) ContainerDelete(ctx context.Context, id cid.ID, prm PrmContainerDelete) error {
func (c *Client) ContainerDelete(ctx context.Context, id cid.ID, prm PrmContainerDelete) (err error) {
ts := time.Now()
defer func() {
c.sendStatistic(stat.MethodContainerDelete, time.Since(ts), err)
}()

signer, err := c.getSigner(prm.signer)
if err != nil {
return err
}

if signer.Scheme() != neofscrypto.ECDSA_DETERMINISTIC_SHA256 {
return errNonNeoSigner
err = errNonNeoSigner
return err
}

// sign container ID
Expand All @@ -340,7 +369,8 @@ func (c *Client) ContainerDelete(ctx context.Context, id cid.ID, prm PrmContaine
var sig neofscrypto.Signature
err = sig.Calculate(signer, data)
if err != nil {
return fmt.Errorf("calculate signature: %w", err)
err = fmt.Errorf("calculate signature: %w", err)
return err
}

var sigv2 refs.Signature
Expand Down Expand Up @@ -383,6 +413,7 @@ func (c *Client) ContainerDelete(ctx context.Context, id cid.ID, prm PrmContaine

// process call
if !cc.processCall() {
err = cc.err
return cc.err
}

Expand All @@ -403,9 +434,15 @@ type PrmContainerEACL struct {
//
// Return errors:
// - [ErrMissingSigner]
func (c *Client) ContainerEACL(ctx context.Context, id cid.ID, prm PrmContainerEACL) (eacl.Table, error) {
func (c *Client) ContainerEACL(ctx context.Context, id cid.ID, prm PrmContainerEACL) (_ eacl.Table, err error) {
ts := time.Now()
defer func() {
c.sendStatistic(stat.MethodContainerEACL, time.Since(ts), err)
}()

if c.prm.signer == nil {
return eacl.Table{}, ErrMissingSigner
err = ErrMissingSigner
return eacl.Table{}, err
}

var cidV2 refs.ContainerID
Expand Down Expand Up @@ -447,6 +484,7 @@ func (c *Client) ContainerEACL(ctx context.Context, id cid.ID, prm PrmContainerE

// process call
if !cc.processCall() {
err = cc.err
return eacl.Table{}, cc.err
}

Expand Down Expand Up @@ -502,19 +540,26 @@ func (x *PrmContainerSetEACL) WithinSession(s session.Container) {
// - [ErrMissingSigner]
//
// Context is required and must not be nil. It is used for network communication.
func (c *Client) ContainerSetEACL(ctx context.Context, table eacl.Table, prm PrmContainerSetEACL) error {
func (c *Client) ContainerSetEACL(ctx context.Context, table eacl.Table, prm PrmContainerSetEACL) (err error) {
ts := time.Now()
defer func() {
c.sendStatistic(stat.MethodContainerSetEACL, time.Since(ts), err)
}()

signer, err := c.getSigner(prm.signer)
if err != nil {
return err
}

if signer.Scheme() != neofscrypto.ECDSA_DETERMINISTIC_SHA256 {
return errNonNeoSigner
err = errNonNeoSigner
return err
}

_, isCIDSet := table.CID()
if !isCIDSet {
return ErrMissingEACLContainer
err = ErrMissingEACLContainer
return err
}

// sign the eACL table
Expand All @@ -523,7 +568,8 @@ func (c *Client) ContainerSetEACL(ctx context.Context, table eacl.Table, prm Prm
var sig neofscrypto.Signature
err = sig.CalculateMarshalled(signer, eaclV2)
if err != nil {
return fmt.Errorf("calculate signature: %w", err)
err = fmt.Errorf("calculate signature: %w", err)
return err
}

var sigv2 refs.Signature
Expand Down Expand Up @@ -566,6 +612,7 @@ func (c *Client) ContainerSetEACL(ctx context.Context, table eacl.Table, prm Prm

// process call
if !cc.processCall() {
err = cc.err
return cc.err
}

Expand Down Expand Up @@ -594,15 +641,20 @@ type PrmAnnounceSpace struct {
// Return errors:
// - [ErrMissingAnnouncements]
// - [ErrMissingSigner]
func (c *Client) ContainerAnnounceUsedSpace(ctx context.Context, announcements []container.SizeEstimation, prm PrmAnnounceSpace) error {
// check parameters
func (c *Client) ContainerAnnounceUsedSpace(ctx context.Context, announcements []container.SizeEstimation, prm PrmAnnounceSpace) (err error) {
ts := time.Now()
defer func() {
c.sendStatistic(stat.MethodContainerAnnounceUsedSpace, time.Since(ts), err)
}()

if len(announcements) == 0 {
return ErrMissingAnnouncements
err = ErrMissingAnnouncements
return err
}

if c.prm.signer == nil {
return ErrMissingSigner
err = ErrMissingSigner
return err
}

// convert list of SDK announcement structures into NeoFS-API v2 list
Expand Down Expand Up @@ -635,6 +687,7 @@ func (c *Client) ContainerAnnounceUsedSpace(ctx context.Context, announcements [

// process call
if !cc.processCall() {
err = cc.err
return cc.err
}

Expand All @@ -650,10 +703,16 @@ func (c *Client) ContainerAnnounceUsedSpace(ctx context.Context, announcements [
// Returns any network/parsing config errors.
//
// See also NetworkInfo, container.ApplyNetworkConfig.
func SyncContainerWithNetwork(ctx context.Context, cnr *container.Container, c *Client) error {
func SyncContainerWithNetwork(ctx context.Context, cnr *container.Container, c *Client) (err error) {
ts := time.Now()
defer func() {
c.sendStatistic(stat.MethodContainerAnnounceUsedSpace, time.Since(ts), err)
}()

res, err := c.NetworkInfo(ctx, PrmNetworkInfo{})
if err != nil {
return fmt.Errorf("network info call: %w", err)
err = fmt.Errorf("network info call: %w", err)
return err
}

cnr.ApplyNetworkConfig(res)
Expand Down
55 changes: 12 additions & 43 deletions pool/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package pool

import (
"context"
"time"

"github.com/nspcc-dev/neofs-sdk-go/client"
"github.com/nspcc-dev/neofs-sdk-go/container"
Expand All @@ -15,100 +14,70 @@ import (
//
// See details in [client.Client.ContainerPut].
func (p *Pool) ContainerPut(ctx context.Context, cont container.Container, prm client.PrmContainerPut) (cid.ID, error) {
c, statUpdater, err := p.sdkClient()
c, _, err := p.sdkClient()
if err != nil {
return cid.ID{}, err
}

start := time.Now()
id, err := c.ContainerPut(ctx, cont, prm)
statUpdater.incRequests(time.Since(start), methodContainerPut)
statUpdater.updateErrorRate(err)

return id, err
return c.ContainerPut(ctx, cont, prm)
}

// ContainerGet reads NeoFS container by ID.
//
// See details in [client.Client.ContainerGet].
func (p *Pool) ContainerGet(ctx context.Context, id cid.ID, prm client.PrmContainerGet) (container.Container, error) {
c, statUpdater, err := p.sdkClient()
c, _, err := p.sdkClient()
if err != nil {
return container.Container{}, err
}

start := time.Now()
cnr, err := c.ContainerGet(ctx, id, prm)
statUpdater.incRequests(time.Since(start), methodContainerGet)
statUpdater.updateErrorRate(err)

return cnr, err
return c.ContainerGet(ctx, id, prm)
}

// ContainerList requests identifiers of the account-owned containers.
//
// See details in [client.Client.ContainerList].
func (p *Pool) ContainerList(ctx context.Context, ownerID user.ID, prm client.PrmContainerList) ([]cid.ID, error) {
c, statUpdater, err := p.sdkClient()
c, _, err := p.sdkClient()
if err != nil {
return []cid.ID{}, err
}

start := time.Now()
ids, err := c.ContainerList(ctx, ownerID, prm)
statUpdater.incRequests(time.Since(start), methodContainerList)
statUpdater.updateErrorRate(err)

return ids, err
return c.ContainerList(ctx, ownerID, prm)
}

// ContainerDelete sends request to remove the NeoFS container.
//
// See details in [client.Client.ContainerDelete].
func (p *Pool) ContainerDelete(ctx context.Context, id cid.ID, prm client.PrmContainerDelete) error {
c, statUpdater, err := p.sdkClient()
c, _, err := p.sdkClient()
if err != nil {
return err
}

start := time.Now()
err = c.ContainerDelete(ctx, id, prm)
statUpdater.incRequests(time.Since(start), methodContainerDelete)
statUpdater.updateErrorRate(err)

return err
return c.ContainerDelete(ctx, id, prm)
}

// ContainerEACL reads eACL table of the NeoFS container.
//
// See details in [client.Client.ContainerEACL].
func (p *Pool) ContainerEACL(ctx context.Context, id cid.ID, prm client.PrmContainerEACL) (eacl.Table, error) {
c, statUpdater, err := p.sdkClient()
c, _, err := p.sdkClient()
if err != nil {
return eacl.Table{}, err
}

start := time.Now()
table, err := c.ContainerEACL(ctx, id, prm)
statUpdater.incRequests(time.Since(start), methodContainerEACL)
statUpdater.updateErrorRate(err)

return table, err
return c.ContainerEACL(ctx, id, prm)
}

// ContainerSetEACL sends request to update eACL table of the NeoFS container.
//
// See details in [client.Client.ContainerSetEACL].
func (p *Pool) ContainerSetEACL(ctx context.Context, table eacl.Table, prm client.PrmContainerSetEACL) error {
c, statUpdater, err := p.sdkClient()
c, _, err := p.sdkClient()
if err != nil {
return err
}

start := time.Now()
err = c.ContainerSetEACL(ctx, table, prm)
statUpdater.incRequests(time.Since(start), methodContainerSetEACL)
statUpdater.updateErrorRate(err)

return err
return c.ContainerSetEACL(ctx, table, prm)
}
Loading

0 comments on commit d5cea25

Please sign in to comment.