Select Git revision
expr_test.go
caching_middleware.go 5.67 KiB
package middleware
import (
"context"
"strings"
"git.perx.ru/perxis/perxis-go/pkg/cache"
envService "git.perx.ru/perxis/perxis-go/pkg/environments"
service "git.perx.ru/perxis/perxis-go/pkg/items"
)
func makeKey(ss ...string) string {
return strings.Join(ss, "-")
}
func CachingMiddleware(cache, cachePublished cache.Cache, envs envService.Environments) Middleware {
return func(next service.Items) service.Items {
return &cachingMiddleware{
cache: cache,
cachePublished: cachePublished,
Items: next,
envs: envs,
}
}
}
type cachingMiddleware struct {
cache cache.Cache
cachePublished cache.Cache
envs envService.Environments
service.Items
}
func (m cachingMiddleware) Get(ctx context.Context, spaceId, envId, collectionId, itemId string, options ...*service.GetOptions) (itm *service.Item, err error) {
value, e := m.cache.Get(makeKey(spaceId, envId, collectionId, itemId))
if e == nil {
return value.(*service.Item).Clone(), err
}
itm, err = m.Items.Get(ctx, spaceId, envId, collectionId, itemId, options...)
if err == nil {
env, err := m.envs.Get(ctx, itm.SpaceID, itm.EnvID)
if err != nil {
return nil, err
}
_ = m.cache.Set(makeKey(itm.SpaceID, env.ID, itm.CollectionID, itm.ID), itm)
for _, al := range env.Aliases {
_ = m.cache.Set(makeKey(itm.SpaceID, al, itm.CollectionID, itm.ID), itm)
}
}
return itm.Clone(), err
}
func (m cachingMiddleware) Update(ctx context.Context, item *service.Item, options ...*service.UpdateOptions) (err error) {
err = m.Items.Update(ctx, item, options...)
if err == nil {
env, err := m.envs.Get(ctx, item.SpaceID, item.EnvID)
if err != nil {
return err
}
_ = m.cache.Remove(makeKey(item.SpaceID, env.ID, item.CollectionID, item.ID))
_ = m.cachePublished.Remove(makeKey(item.SpaceID, env.ID, item.CollectionID, item.ID))
for _, al := range env.Aliases {
_ = m.cache.Remove(makeKey(item.SpaceID, al, item.CollectionID, item.ID))
_ = m.cachePublished.Remove(makeKey(item.SpaceID, al, item.CollectionID, item.ID))
}
}
return err
}
func (m cachingMiddleware) Delete(ctx context.Context, del *service.Item, options ...*service.DeleteOptions) (err error) {
err = m.Items.Delete(ctx, del, options...)
if err == nil {
env, err := m.envs.Get(ctx, del.SpaceID, del.EnvID)
if err != nil {
return err
}
_ = m.cache.Remove(makeKey(del.SpaceID, env.ID, del.CollectionID, del.ID))
_ = m.cachePublished.Remove(makeKey(del.SpaceID, env.ID, del.CollectionID, del.ID))
for _, al := range env.Aliases {
_ = m.cache.Remove(makeKey(del.SpaceID, al, del.CollectionID, del.ID))
_ = m.cachePublished.Remove(makeKey(del.SpaceID, al, del.CollectionID, del.ID))
}
}
return err
}
func (m cachingMiddleware) Publish(ctx context.Context, item *service.Item, options ...*service.PublishOptions) (err error) {
err = m.Items.Publish(ctx, item, options...)
if err == nil {
env, err := m.envs.Get(ctx, item.SpaceID, item.EnvID)
if err != nil {
return err
}
_ = m.cache.Remove(makeKey(item.SpaceID, env.ID, item.CollectionID, item.ID))
_ = m.cachePublished.Remove(makeKey(item.SpaceID, env.ID, item.CollectionID, item.ID))
for _, al := range env.Aliases {
_ = m.cache.Remove(makeKey(item.SpaceID, al, item.CollectionID, item.ID))
_ = m.cachePublished.Remove(makeKey(item.SpaceID, al, item.CollectionID, item.ID))
}
}
return err
}
func (m cachingMiddleware) Unpublish(ctx context.Context, item *service.Item, options ...*service.UnpublishOptions) (err error) {
err = m.Items.Unpublish(ctx, item, options...)
if err == nil {
env, err := m.envs.Get(ctx, item.SpaceID, item.EnvID)
if err != nil {
return err
}
_ = m.cache.Remove(makeKey(item.SpaceID, env.ID, item.CollectionID, item.ID))
_ = m.cachePublished.Remove(makeKey(item.SpaceID, env.ID, item.CollectionID, item.ID))
for _, al := range env.Aliases {
_ = m.cache.Remove(makeKey(item.SpaceID, al, item.CollectionID, item.ID))
_ = m.cachePublished.Remove(makeKey(item.SpaceID, al, item.CollectionID, item.ID))
}
}
return err
}
func (m cachingMiddleware) GetPublished(ctx context.Context, spaceId, envId, collectionId, itemId string, options ...*service.GetPublishedOptions) (itm *service.Item, err error) {
opts := service.MergeGetPublishedOptions(options...)
val, e := m.cachePublished.Get(makeKey(spaceId, envId, collectionId, itemId))
if e == nil {
value := val.(map[string]*service.Item)
if i, ok := value[opts.LocaleID]; ok {
return i.Clone(), nil
}
}
itm, err = m.Items.GetPublished(ctx, spaceId, envId, collectionId, itemId, opts)
if err == nil {
env, err := m.envs.Get(ctx, itm.SpaceID, itm.EnvID)
if err != nil {
return nil, err
}
var value = make(map[string]*service.Item)
if val != nil {
value = val.(map[string]*service.Item)
}
value[opts.LocaleID] = itm
_ = m.cachePublished.Set(makeKey(itm.SpaceID, env.ID, itm.CollectionID, itm.ID), value)
for _, al := range env.Aliases {
_ = m.cachePublished.Set(makeKey(itm.SpaceID, al, itm.CollectionID, itm.ID), value)
}
}
return itm.Clone(), err
}
func (m cachingMiddleware) Archive(ctx context.Context, item *service.Item, options ...*service.ArchiveOptions) (err error) {
err = m.Items.Archive(ctx, item, options...)
if err == nil {
env, err := m.envs.Get(ctx, item.SpaceID, item.EnvID)
if err != nil {
return err
}
_ = m.cache.Remove(makeKey(item.SpaceID, env.ID, item.CollectionID, item.ID))
_ = m.cachePublished.Remove(makeKey(item.SpaceID, env.ID, item.CollectionID, item.ID))
for _, al := range env.Aliases {
_ = m.cache.Remove(makeKey(item.SpaceID, al, item.CollectionID, item.ID))
_ = m.cachePublished.Remove(makeKey(item.SpaceID, al, item.CollectionID, item.ID))
}
}
return err
}