diff --git a/cmd/neofs-node/tree.go b/cmd/neofs-node/tree.go index 91ed24e9..862f9330 100644 --- a/cmd/neofs-node/tree.go +++ b/cmd/neofs-node/tree.go @@ -2,9 +2,14 @@ package main import ( "context" + "errors" treeconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/tree" + "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/pilorama" + "github.com/nspcc-dev/neofs-node/pkg/morph/event" + containerEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/container" "github.com/nspcc-dev/neofs-node/pkg/services/tree" + "go.uber.org/zap" ) func initTreeService(c *cfg) { @@ -32,5 +37,18 @@ func initTreeService(c *cfg) { c.treeService.Start(ctx) })) + subscribeToContainerRemoval(c, func(e event.Event) { + ev := e.(containerEvent.DeleteSuccess) + + // This is executed asynchronously, so we don't care about the operation taking some time. + err := c.treeService.DropTree(context.Background(), ev.ID, "") + if err != nil && !errors.Is(err, pilorama.ErrTreeNotFound) { + // Ignore pilorama.ErrTreeNotFound but other errors, including shard.ErrReadOnly, should be logged. + c.log.Error("container removal event received, but trees weren't removed", + zap.Stringer("cid", ev.ID), + zap.String("error", err.Error())) + } + }) + c.onShutdown(c.treeService.Shutdown) } diff --git a/pkg/services/tree/drop.go b/pkg/services/tree/drop.go new file mode 100644 index 00000000..811938f3 --- /dev/null +++ b/pkg/services/tree/drop.go @@ -0,0 +1,14 @@ +package tree + +import ( + "context" + + cid "github.com/nspcc-dev/neofs-sdk-go/container/id" +) + +// DropTree drops a tree from the database. If treeID is empty, all the trees are dropped. +func (s *Service) DropTree(_ context.Context, cid cid.ID, treeID string) error { + // The only current use-case is a container removal, where all trees should be removed. + // Thus there is no need to replicate the operation on other node. + return s.forest.TreeDrop(cid, treeID) +}