From f73e92c268d601765f9db718dfee832a30a2623a Mon Sep 17 00:00:00 2001 From: Qweder93 Date: Fri, 10 Jul 2020 19:12:31 +0300 Subject: [PATCH] storagenode/gracefulexit: added blobs clean on node's start checks if any of trusted satellites has GE status "Exited successfully" if so - trying to delete blobs/satellite folder, so no trash left on SNO. Change-Id: I566266c84f2a872df54cd01bc2f15a9934f138ed --- storagenode/gracefulexit/blobscleaner.go | 69 ++++++++++++++++++++++++ storagenode/peer.go | 16 +++++- 2 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 storagenode/gracefulexit/blobscleaner.go diff --git a/storagenode/gracefulexit/blobscleaner.go b/storagenode/gracefulexit/blobscleaner.go new file mode 100644 index 000000000..192e874ae --- /dev/null +++ b/storagenode/gracefulexit/blobscleaner.go @@ -0,0 +1,69 @@ +// Copyright (C) 2020 Storj Labs, Inc. +// See LICENSE for copying information. + +package gracefulexit + +import ( + "context" + "database/sql" + "os" + + "go.uber.org/zap" + + "storj.io/storj/storagenode/pieces" + "storj.io/storj/storagenode/satellites" + "storj.io/storj/storagenode/trust" +) + +// BlobsCleaner checks for satellites that the node has completed exit successfully and clear blobs of it. +// +// architecture: Chore +type BlobsCleaner struct { + log *zap.Logger + store *pieces.Store + satelliteDB satellites.DB + trust *trust.Pool +} + +// NewBlobsCleaner instantiates BlobsCleaner. +func NewBlobsCleaner(log *zap.Logger, store *pieces.Store, trust *trust.Pool, satelliteDB satellites.DB) *BlobsCleaner { + return &BlobsCleaner{ + log: log, + store: store, + satelliteDB: satelliteDB, + trust: trust, + } +} + +// RemoveBlobs runs blobs cleaner for satellites on which GE is completed. +// On node's restart checks if any of trusted satellites has GE status "successfully exited" +// Deletes blobs/satellite folder if exists, so if garbage collector didn't clean all SNO won't keep trash. +func (blobsCleaner *BlobsCleaner) RemoveBlobs(ctx context.Context) (err error) { + defer mon.Task()(&ctx)(&err) + + satelliteIDs := blobsCleaner.trust.GetSatellites(ctx) + for i := 0; i < len(satelliteIDs); i++ { + stats, err := blobsCleaner.satelliteDB.GetSatellite(ctx, satelliteIDs[i]) + if err != nil { + if sql.ErrNoRows == err { + continue + } + + blobsCleaner.log.Error("couldn't receive satellite's GE status", zap.Error(err)) + return nil + } + + if stats.Status == satellites.ExitSucceeded { + err = blobsCleaner.store.DeleteSatelliteBlobs(ctx, satelliteIDs[i]) + if err != nil { + if os.IsNotExist(err) { + continue + } + + blobsCleaner.log.Error("couldn't delete blobs/satelliteID folder", zap.Error(err)) + } + } + } + + return nil +} diff --git a/storagenode/peer.go b/storagenode/peer.go index 1589f7601..0b8dbef7b 100644 --- a/storagenode/peer.go +++ b/storagenode/peer.go @@ -247,8 +247,9 @@ type Peer struct { } GracefulExit struct { - Endpoint *gracefulexit.Endpoint - Chore *gracefulexit.Chore + Endpoint *gracefulexit.Endpoint + Chore *gracefulexit.Chore + BlobsCleaner *gracefulexit.BlobsCleaner } Notifications struct { @@ -656,6 +657,17 @@ func New(log *zap.Logger, full *identity.FullIdentity, db DB, revocationDB exten peer.Dialer, peer.DB.Satellites(), ) + peer.GracefulExit.BlobsCleaner = gracefulexit.NewBlobsCleaner( + peer.Log.Named("gracefuexit:blobscleaner"), + peer.Storage2.Store, + peer.Storage2.Trust, + peer.DB.Satellites(), + ) + // Runs once on node start to clean blobs from trash that left after successful GE. + peer.Services.Add(lifecycle.Item{ + Name: "gracefulexit:blobscleaner", + Run: peer.GracefulExit.BlobsCleaner.RemoveBlobs, + }) peer.Services.Add(lifecycle.Item{ Name: "gracefulexit:chore", Run: peer.GracefulExit.Chore.Run,