diff --git a/entry/http/error.go b/entry/http/error.go new file mode 100644 index 0000000..e9fe891 --- /dev/null +++ b/entry/http/error.go @@ -0,0 +1,13 @@ +package http + +const ( + ErrAccessDenied = 4003 //拒绝访问 + ErrPermissionDenied = 4004 //没有权限 + ErrInvalidRequest = 4005 //请求无效或不合法 + ErrInvalidPayload = 4006 //请求数据无效 + ErrResourceCreate = 8001 //资源创建失败 + ErrResourceUpdate = 8002 //资源更新失败 + ErrResourceDelete = 8003 //资源删除失败 + ErrResourceNotFound = 8004 //资源未找到 + ErrTemporaryUnavailable = 8006 //临时性不可用 +) diff --git a/instance.go b/instance.go index 3428979..5feedea 100644 --- a/instance.go +++ b/instance.go @@ -3,6 +3,9 @@ package kos import ( "git.nspix.com/golang/kos/entry/cli" "git.nspix.com/golang/kos/entry/http" + _ "git.nspix.com/golang/kos/util/fetch" + _ "git.nspix.com/golang/kos/util/random" + _ "git.nspix.com/golang/kos/util/reflection" "sync" ) diff --git a/pkg/cache/cache.go b/pkg/cache/cache.go index 4307407..3e15b6b 100644 --- a/pkg/cache/cache.go +++ b/pkg/cache/cache.go @@ -5,9 +5,14 @@ import ( "time" ) +type ( + LoadFunc func(ctx context.Context) (any, error) +) + type Cache interface { Set(ctx context.Context, key string, value any) SetEx(ctx context.Context, key string, value any, expire time.Duration) Get(ctx context.Context, key string) (value any, ok bool) + Try(ctx context.Context, key string, cb LoadFunc) (value any, err error) Del(ctx context.Context, key string) } diff --git a/pkg/cache/instance.go b/pkg/cache/instance.go index 90c2396..3d0a236 100644 --- a/pkg/cache/instance.go +++ b/pkg/cache/instance.go @@ -29,6 +29,10 @@ func SetEx(ctx context.Context, key string, value any, expire time.Duration) { std.SetEx(ctx, key, value, expire) } +func Try(ctx context.Context, key string, cb LoadFunc) (value any, err error) { + return std.Try(ctx, key, cb) +} + func Get(ctx context.Context, key string) (value any, ok bool) { return std.Get(ctx, key) } diff --git a/pkg/cache/memcache.go b/pkg/cache/memcache.go index a7f0c8d..d8061ae 100644 --- a/pkg/cache/memcache.go +++ b/pkg/cache/memcache.go @@ -2,14 +2,50 @@ package cache import ( "context" + "git.nspix.com/golang/kos/util/env" "github.com/patrickmn/go-cache" + "os" "time" ) +var ( + memCacheDefaultExpired time.Duration + memCacheCleanupInterval time.Duration +) + +func init() { + memCacheDefaultExpired, _ = time.ParseDuration(env.Get("MEMCACHE_DEFAULT_EXPIRED", "1h")) + memCacheCleanupInterval, _ = time.ParseDuration(env.Get("MEMCACHE_CLEANUP_INTERVAL", "10m")) + + if memCacheDefaultExpired < time.Second*5 { + memCacheDefaultExpired = time.Second * 5 + } + + if memCacheCleanupInterval < time.Minute { + memCacheCleanupInterval = time.Minute + } +} + type MemCache struct { engine *cache.Cache } +func (cache *MemCache) Try(ctx context.Context, key string, cb LoadFunc) (value any, err error) { + var ( + ok bool + ) + if value, ok = cache.engine.Get(key); ok { + return value, nil + } + if cb == nil { + return nil, os.ErrNotExist + } + if value, err = cb(ctx); err == nil { + cache.engine.Set(key, value, 0) + } + return +} + func (cache *MemCache) Set(ctx context.Context, key string, value any) { cache.engine.Set(key, value, 0) } @@ -28,6 +64,6 @@ func (cache *MemCache) Del(ctx context.Context, key string) { func NewMemCache() *MemCache { return &MemCache{ - engine: cache.New(time.Hour, time.Minute*10), + engine: cache.New(memCacheDefaultExpired, memCacheCleanupInterval), } } diff --git a/util/reflection/reflection.go b/util/reflection/reflection.go new file mode 100644 index 0000000..a289f42 --- /dev/null +++ b/util/reflection/reflection.go @@ -0,0 +1,16 @@ +package reflection + +import "git.nspix.com/golang/kos/util/reflect" + +func Setter(hacky any, variables map[string]any) (err error) { + for k, v := range variables { + if err = Set(hacky, k, v); err != nil { + return err + } + } + return +} + +func Set(hacky any, field string, value interface{}) (err error) { + return reflect.Set(hacky, field, value) +}