Add node addresses as debug information #147
2 changed files with 80 additions and 14 deletions
87
pool/pool.go
87
pool/pool.go
|
@ -2150,7 +2150,7 @@ func (p *Pool) PutObject(ctx context.Context, prm PrmObjectPut) (oid.ID, error)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// removes session token from cache in case of token error
|
// removes session token from cache in case of token error
|
||||||
p.checkSessionTokenErr(err, ctxCall.endpoint)
|
p.checkSessionTokenErr(err, ctxCall.endpoint)
|
||||||
return id, fmt.Errorf("init writing on API client: %w", err)
|
return id, fmt.Errorf("init writing on API client %s: %w", ctxCall.endpoint, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return id, nil
|
return id, nil
|
||||||
|
@ -2193,7 +2193,7 @@ func (p *Pool) DeleteObject(ctx context.Context, prm PrmObjectDelete) error {
|
||||||
|
|
||||||
return p.call(ctx, &cc, func() error {
|
return p.call(ctx, &cc, func() error {
|
||||||
if err = cc.client.objectDelete(ctx, prm); err != nil {
|
if err = cc.client.objectDelete(ctx, prm); err != nil {
|
||||||
return fmt.Errorf("remove object via client: %w", err)
|
return fmt.Errorf("remove object via client %s: %w", cc.endpoint, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -2244,7 +2244,10 @@ func (p *Pool) GetObject(ctx context.Context, prm PrmObjectGet) (ResGetObject, e
|
||||||
|
|
||||||
return res, p.call(ctx, &cc, func() error {
|
return res, p.call(ctx, &cc, func() error {
|
||||||
res, err = cc.client.objectGet(ctx, prm)
|
res, err = cc.client.objectGet(ctx, prm)
|
||||||
return err
|
if err != nil {
|
||||||
|
return fmt.Errorf("get object via client %s: %w", cc.endpoint, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2266,7 +2269,10 @@ func (p *Pool) HeadObject(ctx context.Context, prm PrmObjectHead) (object.Object
|
||||||
|
|
||||||
return obj, p.call(ctx, &cc, func() error {
|
return obj, p.call(ctx, &cc, func() error {
|
||||||
obj, err = cc.client.objectHead(ctx, prm)
|
obj, err = cc.client.objectHead(ctx, prm)
|
||||||
return err
|
if err != nil {
|
||||||
|
return fmt.Errorf("head object via client %s: %w", cc.endpoint, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2314,7 +2320,10 @@ func (p *Pool) ObjectRange(ctx context.Context, prm PrmObjectRange) (ResObjectRa
|
||||||
|
|
||||||
return res, p.call(ctx, &cc, func() error {
|
return res, p.call(ctx, &cc, func() error {
|
||||||
res, err = cc.client.objectRange(ctx, prm)
|
res, err = cc.client.objectRange(ctx, prm)
|
||||||
return err
|
if err != nil {
|
||||||
|
return fmt.Errorf("object range via client %s: %w", cc.endpoint, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2375,7 +2384,10 @@ func (p *Pool) SearchObjects(ctx context.Context, prm PrmObjectSearch) (ResObjec
|
||||||
|
|
||||||
return res, p.call(ctx, &cc, func() error {
|
return res, p.call(ctx, &cc, func() error {
|
||||||
res, err = cc.client.objectSearch(ctx, prm)
|
res, err = cc.client.objectSearch(ctx, prm)
|
||||||
return err
|
if err != nil {
|
||||||
|
return fmt.Errorf("search object via client %s: %w", cc.endpoint, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2395,7 +2407,12 @@ func (p *Pool) PutContainer(ctx context.Context, prm PrmContainerPut) (cid.ID, e
|
||||||
return cid.ID{}, err
|
return cid.ID{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return cp.containerPut(ctx, prm)
|
cnrID, err := cp.containerPut(ctx, prm)
|
||||||
|
if err != nil {
|
||||||
|
return cid.ID{}, fmt.Errorf("put container via client '%s': %w", cp.address(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cnrID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetContainer reads FrostFS container by ID.
|
// GetContainer reads FrostFS container by ID.
|
||||||
|
@ -2407,7 +2424,12 @@ func (p *Pool) GetContainer(ctx context.Context, prm PrmContainerGet) (container
|
||||||
return container.Container{}, err
|
return container.Container{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return cp.containerGet(ctx, prm)
|
cnrs, err := cp.containerGet(ctx, prm)
|
||||||
|
if err != nil {
|
||||||
|
return container.Container{}, fmt.Errorf("get container via client '%s': %w", cp.address(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cnrs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListContainers requests identifiers of the account-owned containers.
|
// ListContainers requests identifiers of the account-owned containers.
|
||||||
|
@ -2417,7 +2439,12 @@ func (p *Pool) ListContainers(ctx context.Context, prm PrmContainerList) ([]cid.
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return cp.containerList(ctx, prm)
|
cnrIDs, err := cp.containerList(ctx, prm)
|
||||||
|
if err != nil {
|
||||||
|
return []cid.ID{}, fmt.Errorf("list containers via client '%s': %w", cp.address(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cnrIDs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteContainer sends request to remove the FrostFS container and waits for the operation to complete.
|
// DeleteContainer sends request to remove the FrostFS container and waits for the operation to complete.
|
||||||
|
@ -2434,7 +2461,12 @@ func (p *Pool) DeleteContainer(ctx context.Context, prm PrmContainerDelete) erro
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return cp.containerDelete(ctx, prm)
|
err = cp.containerDelete(ctx, prm)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("delete container via client '%s': %w", cp.address(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetEACL reads eACL table of the FrostFS container.
|
// GetEACL reads eACL table of the FrostFS container.
|
||||||
|
@ -2446,7 +2478,12 @@ func (p *Pool) GetEACL(ctx context.Context, prm PrmContainerEACL) (eacl.Table, e
|
||||||
return eacl.Table{}, err
|
return eacl.Table{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return cp.containerEACL(ctx, prm)
|
eaclResult, err := cp.containerEACL(ctx, prm)
|
||||||
|
if err != nil {
|
||||||
|
return eacl.Table{}, fmt.Errorf("get EACL via client '%s': %w", cp.address(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return eaclResult, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetEACL sends request to update eACL table of the FrostFS container and waits for the operation to complete.
|
// SetEACL sends request to update eACL table of the FrostFS container and waits for the operation to complete.
|
||||||
|
@ -2463,7 +2500,12 @@ func (p *Pool) SetEACL(ctx context.Context, prm PrmContainerSetEACL) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return cp.containerSetEACL(ctx, prm)
|
err = cp.containerSetEACL(ctx, prm)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("set EACL via client '%s': %w", cp.address(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Balance requests current balance of the FrostFS account.
|
// Balance requests current balance of the FrostFS account.
|
||||||
|
@ -2475,15 +2517,24 @@ func (p *Pool) Balance(ctx context.Context, prm PrmBalanceGet) (accounting.Decim
|
||||||
return accounting.Decimal{}, err
|
return accounting.Decimal{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return cp.balanceGet(ctx, prm)
|
balance, err := cp.balanceGet(ctx, prm)
|
||||||
|
if err != nil {
|
||||||
|
return accounting.Decimal{}, fmt.Errorf("get balance via client '%s': %w", cp.address(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return balance, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Statistic returns connection statistics.
|
// Statistic returns connection statistics.
|
||||||
func (p Pool) Statistic() Statistic {
|
func (p Pool) Statistic() Statistic {
|
||||||
stat := Statistic{}
|
stat := Statistic{}
|
||||||
for _, inner := range p.innerPools {
|
for _, inner := range p.innerPools {
|
||||||
|
nodes := make([]string, 0, len(inner.clients))
|
||||||
inner.lock.RLock()
|
inner.lock.RLock()
|
||||||
for _, cl := range inner.clients {
|
for _, cl := range inner.clients {
|
||||||
|
if cl.isHealthy() {
|
||||||
|
nodes = append(nodes, cl.address())
|
||||||
|
}
|
||||||
node := NodeStatistic{
|
node := NodeStatistic{
|
||||||
address: cl.address(),
|
address: cl.address(),
|
||||||
methods: cl.methodsStatus(),
|
methods: cl.methodsStatus(),
|
||||||
|
@ -2494,6 +2545,9 @@ func (p Pool) Statistic() Statistic {
|
||||||
stat.overallErrors += node.overallErrors
|
stat.overallErrors += node.overallErrors
|
||||||
}
|
}
|
||||||
inner.lock.RUnlock()
|
inner.lock.RUnlock()
|
||||||
|
if len(stat.currentNodes) == 0 {
|
||||||
|
stat.currentNodes = nodes
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return stat
|
return stat
|
||||||
|
@ -2571,7 +2625,12 @@ func (p *Pool) NetworkInfo(ctx context.Context) (netmap.NetworkInfo, error) {
|
||||||
return netmap.NetworkInfo{}, err
|
return netmap.NetworkInfo{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return cp.networkInfo(ctx, prmNetworkInfo{})
|
netInfo, err := cp.networkInfo(ctx, prmNetworkInfo{})
|
||||||
|
if err != nil {
|
||||||
|
return netmap.NetworkInfo{}, fmt.Errorf("get network info via client '%s': %w", cp.address(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return netInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close closes the Pool and releases all the associated resources.
|
// Close closes the Pool and releases all the associated resources.
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
type Statistic struct {
|
type Statistic struct {
|
||||||
overallErrors uint64
|
overallErrors uint64
|
||||||
nodes []NodeStatistic
|
nodes []NodeStatistic
|
||||||
|
currentNodes []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// OverallErrors returns sum of errors on all connections. It doesn't decrease.
|
// OverallErrors returns sum of errors on all connections. It doesn't decrease.
|
||||||
|
@ -21,6 +22,12 @@ func (s Statistic) Nodes() []NodeStatistic {
|
||||||
return s.nodes
|
return s.nodes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CurrentNodes returns list of nodes of inner pool that has at least one healthy node.
|
||||||
|
// These nodes have the same and the highest priority among the other healthy nodes.
|
||||||
|
func (s Statistic) CurrentNodes() []string {
|
||||||
|
return s.currentNodes
|
||||||
|
}
|
||||||
|
|
||||||
// ErrUnknownNode indicate that node with current address is not found in list.
|
// ErrUnknownNode indicate that node with current address is not found in list.
|
||||||
var ErrUnknownNode = errors.New("unknown node")
|
var ErrUnknownNode = errors.New("unknown node")
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue