forked from TrueCloudLab/frostfs-node
[#1632] node/container: Update LIST cache on successful writes
In previous implementation storage node responded with the outdated container list after successful creation/removal up until cache invalidation due to TTL. In order to decrease the probability of outdated responses node should update its cache on event receipts. Implement `ttlContainerLister.update` method which actualizes cached list of the owner's containers. Make node to call `update` method on `PutSuccess`/`DeleteSuccess` notifications from the `Container` contract. Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
d15a7d8d3d
commit
5ce8315cd8
2 changed files with 110 additions and 21 deletions
|
@ -63,12 +63,6 @@ func initContainerService(c *cfg) {
|
|||
neoClient: wrap,
|
||||
}
|
||||
|
||||
subscribeToContainerCreation(c, func(e event.Event) {
|
||||
c.log.Debug("container creation event's receipt",
|
||||
zap.Stringer("id", e.(containerEvent.PutSuccess).ID),
|
||||
)
|
||||
})
|
||||
|
||||
if c.cfgMorph.disableCache {
|
||||
c.cfgObject.eaclSource = eACLFetcher
|
||||
cnrRdr.eacl = eACLFetcher
|
||||
|
@ -81,9 +75,42 @@ func initContainerService(c *cfg) {
|
|||
cachedEACLStorage := newCachedEACLStorage(eACLFetcher)
|
||||
cachedContainerLister := newCachedContainerLister(wrap)
|
||||
|
||||
subscribeToContainerCreation(c, func(e event.Event) {
|
||||
ev := e.(containerEvent.PutSuccess)
|
||||
|
||||
// read owner of the created container in order to update the reading cache.
|
||||
// TODO: use owner directly from the event after neofs-contract#256 will become resolved
|
||||
// but don't forget about the profit of reading the new container and caching it:
|
||||
// creation success are most commonly tracked by polling GET op.
|
||||
cnr, err := cachedContainerStorage.Get(ev.ID)
|
||||
if err == nil {
|
||||
cachedContainerLister.update(cnr.Value.Owner(), ev.ID, true)
|
||||
} else {
|
||||
// unlike removal, we expect successful receive of the container
|
||||
// after successful creation, so logging can be useful
|
||||
c.log.Error("read newly created container after the notification",
|
||||
zap.Stringer("id", ev.ID),
|
||||
zap.Error(err),
|
||||
)
|
||||
}
|
||||
|
||||
c.log.Debug("container creation event's receipt",
|
||||
zap.Stringer("id", ev.ID),
|
||||
)
|
||||
})
|
||||
|
||||
subscribeToContainerRemoval(c, func(e event.Event) {
|
||||
ev := e.(containerEvent.DeleteSuccess)
|
||||
|
||||
// read owner of the removed container in order to update the listing cache.
|
||||
// It's strange to read already removed container, but we can successfully hit
|
||||
// the cache.
|
||||
// TODO: use owner directly from the event after neofs-contract#256 will become resolved
|
||||
cnr, err := cachedContainerStorage.Get(ev.ID)
|
||||
if err == nil {
|
||||
cachedContainerLister.update(cnr.Value.Owner(), ev.ID, false)
|
||||
}
|
||||
|
||||
cachedContainerStorage.handleRemoval(ev.ID)
|
||||
|
||||
c.log.Debug("container removal event's receipt",
|
||||
|
@ -622,16 +649,7 @@ type morphContainerWriter struct {
|
|||
}
|
||||
|
||||
func (m morphContainerWriter) Put(cnr containerCore.Container) (*cid.ID, error) {
|
||||
containerID, err := cntClient.Put(m.neoClient, cnr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if m.cacheEnabled {
|
||||
m.lists.InvalidateContainerList(cnr.Value.Owner())
|
||||
}
|
||||
|
||||
return containerID, nil
|
||||
return cntClient.Put(m.neoClient, cnr)
|
||||
}
|
||||
|
||||
func (m morphContainerWriter) Delete(witness containerCore.RemovalWitness) error {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue