improve package gsession; improve command docker for cli

This commit is contained in:
John Guo
2022-04-26 22:42:56 +08:00
parent eef25c28b4
commit ed0b3c039a
11 changed files with 205 additions and 179 deletions

View File

@ -102,6 +102,7 @@ func (c cDocker) Index(ctx context.Context, in cDockerInput) (out *cDockerOutput
var (
dockerBuildOptions string
dockerTags []string
dockerTagBase string
)
if len(in.TagPrefixes) > 0 {
for _, tagPrefix := range in.TagPrefixes {
@ -112,7 +113,15 @@ func (c cDocker) Index(ctx context.Context, in cDockerInput) (out *cDockerOutput
if len(dockerTags) == 0 {
dockerTags = []string{""}
}
for _, dockerTag := range dockerTags {
for i, dockerTag := range dockerTags {
if i > 0 {
err = gproc.ShellRun(fmt.Sprintf(`docker tag %s %s`, dockerTagBase, dockerTag))
if err != nil {
return
}
continue
}
dockerTagBase = dockerTag
dockerBuildOptions = ""
if dockerTag != "" {
dockerBuildOptions = fmt.Sprintf(`-t %s`, dockerTag)

View File

@ -258,9 +258,14 @@ func Glob(pattern string, onlyNames ...bool) ([]string, error) {
// Remove deletes all file/directory with `path` parameter.
// If parameter `path` is directory, it deletes it recursively.
//
// It does nothing if given `path` does not exist or is empty.
func Remove(path string) (err error) {
err = os.RemoveAll(path)
if err != nil {
// It does nothing if `path` is empty.
if path == "" {
return nil
}
if err = os.RemoveAll(path); err != nil {
err = gerror.Wrapf(err, `os.RemoveAll failed for path "%s"`, path)
}
return

View File

@ -22,7 +22,7 @@ var (
)
// NewSessionId creates and returns a new and unique session id string,
// which is in 36 bytes.
// which is in 32 bytes.
func NewSessionId() string {
return guid.S()
}

View File

@ -23,6 +23,8 @@ type Manager struct {
// sessionData is the memory data cache for session TTL,
// which is available only if the Storage does not store any session data in synchronizing.
// Please refer to the implements of StorageFile, StorageMemory and StorageRedis.
//
// Its value is type of `*gmap.StrAnyMap`.
sessionData *gcache.Cache
}

View File

@ -42,17 +42,19 @@ func (s *Session) init() error {
var err error
if s.id != "" {
// Retrieve memory session data from manager.
r, err := s.manager.sessionData.Get(s.ctx, s.id)
var v *gvar.Var
v, err = s.manager.sessionData.Get(s.ctx, s.id)
if err != nil && err != ErrorDisabled {
return err
}
if r != nil {
s.data = r.Val().(*gmap.StrAnyMap)
if v != nil {
s.data = v.Val().(*gmap.StrAnyMap)
intlog.Print(s.ctx, "session init data:", s.data)
}
// Retrieve stored session data from storage.
if s.manager.storage != nil {
if s.data, err = s.manager.storage.GetSession(s.ctx, s.id, s.manager.ttl, s.data); err != nil && err != ErrorDisabled {
s.data, err = s.manager.storage.GetSession(s.ctx, s.id, s.manager.ttl, s.data)
if err != nil && err != ErrorDisabled {
intlog.Errorf(s.ctx, `session restoring failed for id "%s": %+v`, s.id, err)
return err
}
@ -93,11 +95,13 @@ func (s *Session) Close() error {
size := s.data.Size()
if s.manager.storage != nil {
if s.dirty {
if err := s.manager.storage.SetSession(s.ctx, s.id, s.data, s.manager.ttl); err != nil && err != ErrorDisabled {
err := s.manager.storage.SetSession(s.ctx, s.id, s.data, s.manager.ttl)
if err != nil && err != ErrorDisabled {
return err
}
} else if size > 0 {
if err := s.manager.storage.UpdateTTL(s.ctx, s.id, s.manager.ttl); err != nil && err != ErrorDisabled {
err := s.manager.storage.UpdateTTL(s.ctx, s.id, s.manager.ttl)
if err != nil && err != ErrorDisabled {
return err
}
}
@ -109,7 +113,7 @@ func (s *Session) Close() error {
return nil
}
// Set sets key-value pair to this session.
// Set sets sessionIdToRedisKey-value pair to this session.
func (s *Session) Set(key string, value interface{}) error {
if err := s.init(); err != nil {
return err
@ -141,7 +145,7 @@ func (s *Session) SetMap(data map[string]interface{}) error {
return nil
}
// Remove removes key along with its value from this session.
// Remove removes sessionIdToRedisKey along with its value from this session.
func (s *Session) Remove(keys ...string) error {
if s.id == "" {
return nil
@ -162,21 +166,23 @@ func (s *Session) Remove(keys ...string) error {
return nil
}
// RemoveAll deletes all key-value pairs from this session.
func (s *Session) RemoveAll() error {
// RemoveAll deletes all sessionIdToRedisKey-value pairs from this session.
func (s *Session) RemoveAll() (err error) {
if s.id == "" {
return nil
}
if err := s.init(); err != nil {
if err = s.init(); err != nil {
return err
}
if err := s.manager.storage.RemoveAll(s.ctx, s.id); err != nil {
if err == ErrorDisabled {
s.data.Clear()
} else {
if err = s.manager.storage.RemoveAll(s.ctx, s.id); err != nil {
if err != ErrorDisabled {
return err
}
}
// Remove data from memory.
if s.data != nil {
s.data.Clear()
}
s.dirty = true
return nil
}
@ -247,7 +253,7 @@ func (s *Session) Size() (int, error) {
return s.data.Size(), nil
}
// Contains checks whether key exist in the session.
// Contains checks whether sessionIdToRedisKey exist in the session.
func (s *Session) Contains(key string) (bool, error) {
if s.id == "" {
return false, nil
@ -267,8 +273,8 @@ func (s *Session) IsDirty() bool {
return s.dirty
}
// Get retrieves session value with given key.
// It returns `def` if the key does not exist in the session if `def` is given,
// Get retrieves session value with given sessionIdToRedisKey.
// It returns `def` if the sessionIdToRedisKey does not exist in the session if `def` is given,
// or else it returns nil.
func (s *Session) Get(key string, def ...interface{}) (*gvar.Var, error) {
if s.id == "" {

View File

@ -17,47 +17,47 @@ import (
type Storage interface {
// New creates a custom session id.
// This function can be used for custom session creation.
New(ctx context.Context, ttl time.Duration) (id string, err error)
New(ctx context.Context, ttl time.Duration) (sessionId string, err error)
// Get retrieves and returns session value with given key.
// It returns nil if the key does not exist in the session.
Get(ctx context.Context, id string, key string) (value interface{}, err error)
// Get retrieves and returns session value with given sessionIdToRedisKey.
// It returns nil if the sessionIdToRedisKey does not exist in the session.
Get(ctx context.Context, sessionId string, key string) (value interface{}, err error)
// GetSize retrieves and returns the size of key-value pairs from storage.
GetSize(ctx context.Context, id string) (size int, err error)
// GetSize retrieves and returns the size of sessionIdToRedisKey-value pairs from storage.
GetSize(ctx context.Context, sessionId string) (size int, err error)
// Data retrieves all key-value pairs as map from storage.
Data(ctx context.Context, id string) (data map[string]interface{}, err error)
// Data retrieves all sessionIdToRedisKey-value pairs as map from storage.
Data(ctx context.Context, sessionId string) (data map[string]interface{}, err error)
// Set sets one key-value session pair to the storage.
// Set sets one sessionIdToRedisKey-value session pair to the storage.
// The parameter `ttl` specifies the TTL for the session id.
Set(ctx context.Context, id string, key string, value interface{}, ttl time.Duration) error
Set(ctx context.Context, sessionId string, key string, value interface{}, ttl time.Duration) error
// SetMap batch sets key-value session pairs as map to the storage.
// SetMap batch sets sessionIdToRedisKey-value session pairs as map to the storage.
// The parameter `ttl` specifies the TTL for the session id.
SetMap(ctx context.Context, id string, data map[string]interface{}, ttl time.Duration) error
SetMap(ctx context.Context, sessionId string, data map[string]interface{}, ttl time.Duration) error
// Remove deletes key with its value from storage.
Remove(ctx context.Context, id string, key string) error
// Remove deletes sessionIdToRedisKey with its value from storage.
Remove(ctx context.Context, sessionId string, key string) error
// RemoveAll deletes all key-value pairs from storage.
RemoveAll(ctx context.Context, id string) error
// RemoveAll deletes all sessionIdToRedisKey-value pairs from storage.
RemoveAll(ctx context.Context, sessionId string) error
// GetSession returns the session data as `*gmap.StrAnyMap` for given session id from storage.
// GetSession returns the session data as `*gmap.StrAnyMap` for given session from storage.
//
// The parameter `ttl` specifies the TTL for this session.
// The parameter `data` is the current old session data stored in memory,
// and for some storage it might be nil if memory storage is disabled.
//
// This function is called ever when session starts. It returns nil if the TTL is exceeded.
GetSession(ctx context.Context, id string, ttl time.Duration, data *gmap.StrAnyMap) (*gmap.StrAnyMap, error)
GetSession(ctx context.Context, sessionId string, ttl time.Duration, data *gmap.StrAnyMap) (*gmap.StrAnyMap, error)
// SetSession updates the data for specified session id.
// This function is called ever after session, which is changed dirty, is closed.
// This copy all session data map from memory to storage.
SetSession(ctx context.Context, id string, data *gmap.StrAnyMap, ttl time.Duration) error
SetSession(ctx context.Context, sessionId string, data *gmap.StrAnyMap, ttl time.Duration) error
// UpdateTTL updates the TTL for specified session id.
// This function is called ever after session, which is not dirty, is closed.
UpdateTTL(ctx context.Context, id string, ttl time.Duration) error
UpdateTTL(ctx context.Context, sessionId string, ttl time.Duration) error
}

View File

@ -39,7 +39,7 @@ const (
var (
DefaultStorageFilePath = gfile.Temp("gsessions")
DefaultStorageFileCryptoKey = []byte("Session storage file crypto key!")
DefaultStorageFileCryptoKey = []byte("Session storage file crypto sessionIdToRedisKey!")
)
// NewStorageFile creates and returns a file storage object for session.
@ -73,22 +73,22 @@ func NewStorageFile(path ...string) *StorageFile {
// updateSessionTimely batch updates the TTL for sessions timely.
func (s *StorageFile) updateSessionTimely(ctx context.Context) {
var (
id string
err error
sessionId string
err error
)
// Batch updating sessions.
for {
if id = s.updatingIdSet.Pop(); id == "" {
if sessionId = s.updatingIdSet.Pop(); sessionId == "" {
break
}
if err = s.updateSessionTTl(context.TODO(), id); err != nil {
if err = s.updateSessionTTl(context.TODO(), sessionId); err != nil {
intlog.Errorf(context.TODO(), `%+v`, err)
}
}
}
// SetCryptoKey sets the crypto key for session storage.
// The crypto key is used when crypto feature is enabled.
// SetCryptoKey sets the crypto sessionIdToRedisKey for session storage.
// The crypto sessionIdToRedisKey is used when crypto feature is enabled.
func (s *StorageFile) SetCryptoKey(key []byte) {
s.cryptoKey = key
}
@ -109,42 +109,42 @@ func (s *StorageFile) New(ctx context.Context, ttl time.Duration) (id string, er
return "", ErrorDisabled
}
// Get retrieves session value with given key.
// It returns nil if the key does not exist in the session.
func (s *StorageFile) Get(ctx context.Context, id string, key string) (value interface{}, err error) {
// Get retrieves session value with given sessionIdToRedisKey.
// It returns nil if the sessionIdToRedisKey does not exist in the session.
func (s *StorageFile) Get(ctx context.Context, sessionId string, key string) (value interface{}, err error) {
return nil, ErrorDisabled
}
// Data retrieves all key-value pairs as map from storage.
func (s *StorageFile) Data(ctx context.Context, id string) (data map[string]interface{}, err error) {
// Data retrieves all sessionIdToRedisKey-value pairs as map from storage.
func (s *StorageFile) Data(ctx context.Context, sessionId string) (data map[string]interface{}, err error) {
return nil, ErrorDisabled
}
// GetSize retrieves the size of key-value pairs from storage.
func (s *StorageFile) GetSize(ctx context.Context, id string) (size int, err error) {
// GetSize retrieves the size of sessionIdToRedisKey-value pairs from storage.
func (s *StorageFile) GetSize(ctx context.Context, sessionId string) (size int, err error) {
return -1, ErrorDisabled
}
// Set sets key-value session pair to the storage.
// The parameter `ttl` specifies the TTL for the session id (not for the key-value pair).
func (s *StorageFile) Set(ctx context.Context, id string, key string, value interface{}, ttl time.Duration) error {
// Set sets sessionIdToRedisKey-value session pair to the storage.
// The parameter `ttl` specifies the TTL for the session id (not for the sessionIdToRedisKey-value pair).
func (s *StorageFile) Set(ctx context.Context, sessionId string, key string, value interface{}, ttl time.Duration) error {
return ErrorDisabled
}
// SetMap batch sets key-value session pairs with map to the storage.
// The parameter `ttl` specifies the TTL for the session id(not for the key-value pair).
func (s *StorageFile) SetMap(ctx context.Context, id string, data map[string]interface{}, ttl time.Duration) error {
// SetMap batch sets sessionIdToRedisKey-value session pairs with map to the storage.
// The parameter `ttl` specifies the TTL for the session id(not for the sessionIdToRedisKey-value pair).
func (s *StorageFile) SetMap(ctx context.Context, sessionId string, data map[string]interface{}, ttl time.Duration) error {
return ErrorDisabled
}
// Remove deletes key with its value from storage.
func (s *StorageFile) Remove(ctx context.Context, id string, key string) error {
// Remove deletes sessionIdToRedisKey with its value from storage.
func (s *StorageFile) Remove(ctx context.Context, sessionId string, key string) error {
return ErrorDisabled
}
// RemoveAll deletes all key-value pairs from storage.
func (s *StorageFile) RemoveAll(ctx context.Context, id string) error {
return ErrorDisabled
// RemoveAll deletes all sessionIdToRedisKey-value pairs from storage.
func (s *StorageFile) RemoveAll(ctx context.Context, sessionId string) error {
return gfile.Remove(s.sessionFilePath(sessionId))
}
// GetSession returns the session data as *gmap.StrAnyMap for given session id from storage.
@ -154,12 +154,15 @@ func (s *StorageFile) RemoveAll(ctx context.Context, id string) error {
// and for some storage it might be nil if memory storage is disabled.
//
// This function is called ever when session starts.
func (s *StorageFile) GetSession(ctx context.Context, id string, ttl time.Duration, data *gmap.StrAnyMap) (*gmap.StrAnyMap, error) {
func (s *StorageFile) GetSession(ctx context.Context, sessionId string, ttl time.Duration, data *gmap.StrAnyMap) (*gmap.StrAnyMap, error) {
if data != nil {
return data, nil
}
path := s.sessionFilePath(id)
content := gfile.GetBytes(path)
var (
path = s.sessionFilePath(sessionId)
content = gfile.GetBytes(path)
)
// It updates the TTL only if the session file already exists.
if len(content) > 8 {
timestampMilli := gbinary.DecodeToInt64(content[:8])
if timestampMilli+ttl.Nanoseconds()/1e6 < gtime.TimestampMilli() {
@ -189,9 +192,9 @@ func (s *StorageFile) GetSession(ctx context.Context, id string, ttl time.Durati
// SetSession updates the data map for specified session id.
// This function is called ever after session, which is changed dirty, is closed.
// This copy all session data map from memory to storage.
func (s *StorageFile) SetSession(ctx context.Context, id string, data *gmap.StrAnyMap, ttl time.Duration) error {
intlog.Printf(ctx, "StorageFile.SetSession: %s, %v, %v", id, data, ttl)
path := s.sessionFilePath(id)
func (s *StorageFile) SetSession(ctx context.Context, sessionId string, data *gmap.StrAnyMap, ttl time.Duration) error {
intlog.Printf(ctx, "StorageFile.SetSession: %s, %v, %v", sessionId, data, ttl)
path := s.sessionFilePath(sessionId)
content, err := json.Marshal(data)
if err != nil {
return err
@ -224,18 +227,18 @@ func (s *StorageFile) SetSession(ctx context.Context, id string, data *gmap.StrA
// UpdateTTL updates the TTL for specified session id.
// This function is called ever after session, which is not dirty, is closed.
// It just adds the session id to the async handling queue.
func (s *StorageFile) UpdateTTL(ctx context.Context, id string, ttl time.Duration) error {
intlog.Printf(ctx, "StorageFile.UpdateTTL: %s, %v", id, ttl)
func (s *StorageFile) UpdateTTL(ctx context.Context, sessionId string, ttl time.Duration) error {
intlog.Printf(ctx, "StorageFile.UpdateTTL: %s, %v", sessionId, ttl)
if ttl >= DefaultStorageFileLoopInterval {
s.updatingIdSet.Add(id)
s.updatingIdSet.Add(sessionId)
}
return nil
}
// updateSessionTTL updates the TTL for specified session id.
func (s *StorageFile) updateSessionTTl(ctx context.Context, id string) error {
intlog.Printf(ctx, "StorageFile.updateSession: %s", id)
path := s.sessionFilePath(id)
func (s *StorageFile) updateSessionTTl(ctx context.Context, sessionId string) error {
intlog.Printf(ctx, "StorageFile.updateSession: %s", sessionId)
path := s.sessionFilePath(sessionId)
file, err := gfile.OpenWithFlag(path, os.O_WRONLY)
if err != nil {
return err

View File

@ -27,41 +27,41 @@ func (s *StorageMemory) New(ctx context.Context, ttl time.Duration) (id string,
return "", ErrorDisabled
}
// Get retrieves session value with given key.
// It returns nil if the key does not exist in the session.
func (s *StorageMemory) Get(ctx context.Context, id string, key string) (value interface{}, err error) {
// Get retrieves session value with given sessionIdToRedisKey.
// It returns nil if the sessionIdToRedisKey does not exist in the session.
func (s *StorageMemory) Get(ctx context.Context, sessionId string, key string) (value interface{}, err error) {
return nil, ErrorDisabled
}
// GetMap retrieves all key-value pairs as map from storage.
func (s *StorageMemory) Data(ctx context.Context, id string) (data map[string]interface{}, err error) {
// Data retrieves all sessionIdToRedisKey-value pairs as map from storage.
func (s *StorageMemory) Data(ctx context.Context, sessionId string) (data map[string]interface{}, err error) {
return nil, ErrorDisabled
}
// GetSize retrieves the size of key-value pairs from storage.
func (s *StorageMemory) GetSize(ctx context.Context, id string) (size int, err error) {
// GetSize retrieves the size of sessionIdToRedisKey-value pairs from storage.
func (s *StorageMemory) GetSize(ctx context.Context, sessionId string) (size int, err error) {
return -1, ErrorDisabled
}
// Set sets key-value session pair to the storage.
// The parameter `ttl` specifies the TTL for the session id (not for the key-value pair).
func (s *StorageMemory) Set(ctx context.Context, id string, key string, value interface{}, ttl time.Duration) error {
// Set sets sessionIdToRedisKey-value session pair to the storage.
// The parameter `ttl` specifies the TTL for the session id (not for the sessionIdToRedisKey-value pair).
func (s *StorageMemory) Set(ctx context.Context, sessionId string, key string, value interface{}, ttl time.Duration) error {
return ErrorDisabled
}
// SetMap batch sets key-value session pairs with map to the storage.
// The parameter `ttl` specifies the TTL for the session id(not for the key-value pair).
func (s *StorageMemory) SetMap(ctx context.Context, id string, data map[string]interface{}, ttl time.Duration) error {
// SetMap batch sets sessionIdToRedisKey-value session pairs with map to the storage.
// The parameter `ttl` specifies the TTL for the session id(not for the sessionIdToRedisKey-value pair).
func (s *StorageMemory) SetMap(ctx context.Context, sessionId string, data map[string]interface{}, ttl time.Duration) error {
return ErrorDisabled
}
// Remove deletes key with its value from storage.
func (s *StorageMemory) Remove(ctx context.Context, id string, key string) error {
// Remove deletes sessionIdToRedisKey with its value from storage.
func (s *StorageMemory) Remove(ctx context.Context, sessionId string, key string) error {
return ErrorDisabled
}
// RemoveAll deletes all key-value pairs from storage.
func (s *StorageMemory) RemoveAll(ctx context.Context, id string) error {
// RemoveAll deletes all sessionIdToRedisKey-value pairs from storage.
func (s *StorageMemory) RemoveAll(ctx context.Context, sessionId string) error {
return ErrorDisabled
}
@ -72,20 +72,20 @@ func (s *StorageMemory) RemoveAll(ctx context.Context, id string) error {
// and for some storage it might be nil if memory storage is disabled.
//
// This function is called ever when session starts.
func (s *StorageMemory) GetSession(ctx context.Context, id string, ttl time.Duration, data *gmap.StrAnyMap) (*gmap.StrAnyMap, error) {
func (s *StorageMemory) GetSession(ctx context.Context, sessionId string, ttl time.Duration, data *gmap.StrAnyMap) (*gmap.StrAnyMap, error) {
return data, nil
}
// SetSession updates the data map for specified session id.
// This function is called ever after session, which is changed dirty, is closed.
// This copy all session data map from memory to storage.
func (s *StorageMemory) SetSession(ctx context.Context, id string, data *gmap.StrAnyMap, ttl time.Duration) error {
func (s *StorageMemory) SetSession(ctx context.Context, sessionId string, data *gmap.StrAnyMap, ttl time.Duration) error {
return nil
}
// UpdateTTL updates the TTL for specified session id.
// This function is called ever after session, which is not dirty, is closed.
// It just adds the session id to the async handling queue.
func (s *StorageMemory) UpdateTTL(ctx context.Context, id string, ttl time.Duration) error {
func (s *StorageMemory) UpdateTTL(ctx context.Context, sessionId string, ttl time.Duration) error {
return nil
}

View File

@ -20,7 +20,7 @@ import (
// StorageRedis implements the Session Storage interface with redis.
type StorageRedis struct {
redis *gredis.Redis // Redis client for session storage.
prefix string // Redis key prefix for session id.
prefix string // Redis sessionIdToRedisKey prefix for session id.
updatingIdMap *gmap.StrIntMap // Updating TTL set for session id.
}
@ -47,15 +47,15 @@ func NewStorageRedis(redis *gredis.Redis, prefix ...string) *StorageRedis {
gtimer.AddSingleton(context.Background(), DefaultStorageRedisLoopInterval, func(ctx context.Context) {
intlog.Print(context.TODO(), "StorageRedis.timer start")
var (
id string
err error
sessionId string
ttlSeconds int
)
for {
if id, ttlSeconds = s.updatingIdMap.Pop(); id == "" {
if sessionId, ttlSeconds = s.updatingIdMap.Pop(); sessionId == "" {
break
} else {
if err = s.doUpdateTTL(context.TODO(), id, ttlSeconds); err != nil {
if err = s.doUpdateTTL(context.TODO(), sessionId, ttlSeconds); err != nil {
intlog.Errorf(context.TODO(), `%+v`, err)
}
}
@ -71,42 +71,43 @@ func (s *StorageRedis) New(ctx context.Context, ttl time.Duration) (id string, e
return "", ErrorDisabled
}
// Get retrieves session value with given key.
// It returns nil if the key does not exist in the session.
func (s *StorageRedis) Get(ctx context.Context, id string, key string) (value interface{}, err error) {
// Get retrieves session value with given sessionIdToRedisKey.
// It returns nil if the sessionIdToRedisKey does not exist in the session.
func (s *StorageRedis) Get(ctx context.Context, sessionId string, key string) (value interface{}, err error) {
return nil, ErrorDisabled
}
// Data retrieves all key-value pairs as map from storage.
func (s *StorageRedis) Data(ctx context.Context, id string) (data map[string]interface{}, err error) {
// Data retrieves all sessionIdToRedisKey-value pairs as map from storage.
func (s *StorageRedis) Data(ctx context.Context, sessionId string) (data map[string]interface{}, err error) {
return nil, ErrorDisabled
}
// GetSize retrieves the size of key-value pairs from storage.
func (s *StorageRedis) GetSize(ctx context.Context, id string) (size int, err error) {
// GetSize retrieves the size of sessionIdToRedisKey-value pairs from storage.
func (s *StorageRedis) GetSize(ctx context.Context, sessionId string) (size int, err error) {
return -1, ErrorDisabled
}
// Set sets key-value session pair to the storage.
// The parameter `ttl` specifies the TTL for the session id (not for the key-value pair).
func (s *StorageRedis) Set(ctx context.Context, id string, key string, value interface{}, ttl time.Duration) error {
// Set sets sessionIdToRedisKey-value session pair to the storage.
// The parameter `ttl` specifies the TTL for the session id (not for the sessionIdToRedisKey-value pair).
func (s *StorageRedis) Set(ctx context.Context, sessionId string, key string, value interface{}, ttl time.Duration) error {
return ErrorDisabled
}
// SetMap batch sets key-value session pairs with map to the storage.
// The parameter `ttl` specifies the TTL for the session id(not for the key-value pair).
func (s *StorageRedis) SetMap(ctx context.Context, id string, data map[string]interface{}, ttl time.Duration) error {
// SetMap batch sets sessionIdToRedisKey-value session pairs with map to the storage.
// The parameter `ttl` specifies the TTL for the session id(not for the sessionIdToRedisKey-value pair).
func (s *StorageRedis) SetMap(ctx context.Context, sessionId string, data map[string]interface{}, ttl time.Duration) error {
return ErrorDisabled
}
// Remove deletes key with its value from storage.
func (s *StorageRedis) Remove(ctx context.Context, id string, key string) error {
// Remove deletes sessionIdToRedisKey with its value from storage.
func (s *StorageRedis) Remove(ctx context.Context, sessionId string, key string) error {
return ErrorDisabled
}
// RemoveAll deletes all key-value pairs from storage.
func (s *StorageRedis) RemoveAll(ctx context.Context, id string) error {
return ErrorDisabled
// RemoveAll deletes all sessionIdToRedisKey-value pairs from storage.
func (s *StorageRedis) RemoveAll(ctx context.Context, sessionId string) error {
_, err := s.redis.Do(ctx, "DEL", s.sessionIdToRedisKey(sessionId))
return err
}
// GetSession returns the session data as *gmap.StrAnyMap for given session id from storage.
@ -116,9 +117,9 @@ func (s *StorageRedis) RemoveAll(ctx context.Context, id string) error {
// and for some storage it might be nil if memory storage is disabled.
//
// This function is called ever when session starts.
func (s *StorageRedis) GetSession(ctx context.Context, id string, ttl time.Duration, data *gmap.StrAnyMap) (*gmap.StrAnyMap, error) {
intlog.Printf(ctx, "StorageRedis.GetSession: %s, %v", id, ttl)
r, err := s.redis.Do(ctx, "GET", s.key(id))
func (s *StorageRedis) GetSession(ctx context.Context, sessionId string, ttl time.Duration, data *gmap.StrAnyMap) (*gmap.StrAnyMap, error) {
intlog.Printf(ctx, "StorageRedis.GetSession: %s, %v", sessionId, ttl)
r, err := s.redis.Do(ctx, "GET", s.sessionIdToRedisKey(sessionId))
if err != nil {
return nil, err
}
@ -143,34 +144,34 @@ func (s *StorageRedis) GetSession(ctx context.Context, id string, ttl time.Durat
// SetSession updates the data map for specified session id.
// This function is called ever after session, which is changed dirty, is closed.
// This copy all session data map from memory to storage.
func (s *StorageRedis) SetSession(ctx context.Context, id string, data *gmap.StrAnyMap, ttl time.Duration) error {
intlog.Printf(ctx, "StorageRedis.SetSession: %s, %v, %v", id, data, ttl)
func (s *StorageRedis) SetSession(ctx context.Context, sessionId string, data *gmap.StrAnyMap, ttl time.Duration) error {
intlog.Printf(ctx, "StorageRedis.SetSession: %s, %v, %v", sessionId, data, ttl)
content, err := json.Marshal(data)
if err != nil {
return err
}
_, err = s.redis.Do(ctx, "SETEX", s.key(id), int64(ttl.Seconds()), content)
_, err = s.redis.Do(ctx, "SETEX", s.sessionIdToRedisKey(sessionId), int64(ttl.Seconds()), content)
return err
}
// UpdateTTL updates the TTL for specified session id.
// This function is called ever after session, which is not dirty, is closed.
// It just adds the session id to the async handling queue.
func (s *StorageRedis) UpdateTTL(ctx context.Context, id string, ttl time.Duration) error {
intlog.Printf(ctx, "StorageRedis.UpdateTTL: %s, %v", id, ttl)
func (s *StorageRedis) UpdateTTL(ctx context.Context, sessionId string, ttl time.Duration) error {
intlog.Printf(ctx, "StorageRedis.UpdateTTL: %s, %v", sessionId, ttl)
if ttl >= DefaultStorageRedisLoopInterval {
s.updatingIdMap.Set(id, int(ttl.Seconds()))
s.updatingIdMap.Set(sessionId, int(ttl.Seconds()))
}
return nil
}
// doUpdateTTL updates the TTL for session id.
func (s *StorageRedis) doUpdateTTL(ctx context.Context, id string, ttlSeconds int) error {
intlog.Printf(ctx, "StorageRedis.doUpdateTTL: %s, %d", id, ttlSeconds)
_, err := s.redis.Do(ctx, "EXPIRE", s.key(id), ttlSeconds)
func (s *StorageRedis) doUpdateTTL(ctx context.Context, sessionId string, ttlSeconds int) error {
intlog.Printf(ctx, "StorageRedis.doUpdateTTL: %s, %d", sessionId, ttlSeconds)
_, err := s.redis.Do(ctx, "EXPIRE", s.sessionIdToRedisKey(sessionId), ttlSeconds)
return err
}
func (s *StorageRedis) key(id string) string {
return s.prefix + id
func (s *StorageRedis) sessionIdToRedisKey(sessionId string) string {
return s.prefix + sessionId
}

View File

@ -19,7 +19,7 @@ import (
// StorageRedisHashTable implements the Session Storage interface with redis hash table.
type StorageRedisHashTable struct {
redis *gredis.Redis // Redis client for session storage.
prefix string // Redis key prefix for session id.
prefix string // Redis sessionIdToRedisKey prefix for session id.
}
// NewStorageRedisHashTable creates and returns a redis hash table storage object for session.
@ -43,10 +43,10 @@ func (s *StorageRedisHashTable) New(ctx context.Context, ttl time.Duration) (id
return "", ErrorDisabled
}
// Get retrieves session value with given key.
// It returns nil if the key does not exist in the session.
func (s *StorageRedisHashTable) Get(ctx context.Context, id string, key string) (value interface{}, err error) {
v, err := s.redis.Do(ctx, "HGET", s.key(id), key)
// Get retrieves session value with given sessionIdToRedisKey.
// It returns nil if the sessionIdToRedisKey does not exist in the session.
func (s *StorageRedisHashTable) Get(ctx context.Context, sessionId string, key string) (value interface{}, err error) {
v, err := s.redis.Do(ctx, "HGET", s.sessionIdToRedisKey(sessionId), key)
if err != nil {
return nil, err
}
@ -56,9 +56,9 @@ func (s *StorageRedisHashTable) Get(ctx context.Context, id string, key string)
return v.String(), nil
}
// Data retrieves all key-value pairs as map from storage.
func (s *StorageRedisHashTable) Data(ctx context.Context, id string) (data map[string]interface{}, err error) {
v, err := s.redis.Do(ctx, "HGETALL", s.key(id))
// Data retrieves all sessionIdToRedisKey-value pairs as map from storage.
func (s *StorageRedisHashTable) Data(ctx context.Context, sessionId string) (data map[string]interface{}, err error) {
v, err := s.redis.Do(ctx, "HGETALL", s.sessionIdToRedisKey(sessionId))
if err != nil {
return nil, err
}
@ -74,27 +74,27 @@ func (s *StorageRedisHashTable) Data(ctx context.Context, id string) (data map[s
return data, nil
}
// GetSize retrieves the size of key-value pairs from storage.
func (s *StorageRedisHashTable) GetSize(ctx context.Context, id string) (size int, err error) {
r, err := s.redis.Do(ctx, "HLEN", s.key(id))
// GetSize retrieves the size of sessionIdToRedisKey-value pairs from storage.
func (s *StorageRedisHashTable) GetSize(ctx context.Context, sessionId string) (size int, err error) {
r, err := s.redis.Do(ctx, "HLEN", s.sessionIdToRedisKey(sessionId))
if err != nil {
return -1, err
}
return r.Int(), nil
}
// Set sets key-value session pair to the storage.
// The parameter `ttl` specifies the TTL for the session id (not for the key-value pair).
func (s *StorageRedisHashTable) Set(ctx context.Context, id string, key string, value interface{}, ttl time.Duration) error {
_, err := s.redis.Do(ctx, "HSET", s.key(id), key, value)
// Set sets sessionIdToRedisKey-value session pair to the storage.
// The parameter `ttl` specifies the TTL for the session id (not for the sessionIdToRedisKey-value pair).
func (s *StorageRedisHashTable) Set(ctx context.Context, sessionId string, key string, value interface{}, ttl time.Duration) error {
_, err := s.redis.Do(ctx, "HSET", s.sessionIdToRedisKey(sessionId), key, value)
return err
}
// SetMap batch sets key-value session pairs with map to the storage.
// The parameter `ttl` specifies the TTL for the session id(not for the key-value pair).
func (s *StorageRedisHashTable) SetMap(ctx context.Context, id string, data map[string]interface{}, ttl time.Duration) error {
// SetMap batch sets sessionIdToRedisKey-value session pairs with map to the storage.
// The parameter `ttl` specifies the TTL for the session id(not for the sessionIdToRedisKey-value pair).
func (s *StorageRedisHashTable) SetMap(ctx context.Context, sessionId string, data map[string]interface{}, ttl time.Duration) error {
array := make([]interface{}, len(data)*2+1)
array[0] = s.key(id)
array[0] = s.sessionIdToRedisKey(sessionId)
index := 1
for k, v := range data {
@ -106,15 +106,15 @@ func (s *StorageRedisHashTable) SetMap(ctx context.Context, id string, data map[
return err
}
// Remove deletes key with its value from storage.
func (s *StorageRedisHashTable) Remove(ctx context.Context, id string, key string) error {
_, err := s.redis.Do(ctx, "HDEL", s.key(id), key)
// Remove deletes sessionIdToRedisKey with its value from storage.
func (s *StorageRedisHashTable) Remove(ctx context.Context, sessionId string, key string) error {
_, err := s.redis.Do(ctx, "HDEL", s.sessionIdToRedisKey(sessionId), key)
return err
}
// RemoveAll deletes all key-value pairs from storage.
func (s *StorageRedisHashTable) RemoveAll(ctx context.Context, id string) error {
_, err := s.redis.Do(ctx, "DEL", s.key(id))
// RemoveAll deletes all sessionIdToRedisKey-value pairs from storage.
func (s *StorageRedisHashTable) RemoveAll(ctx context.Context, sessionId string) error {
_, err := s.redis.Do(ctx, "DEL", s.sessionIdToRedisKey(sessionId))
return err
}
@ -125,9 +125,9 @@ func (s *StorageRedisHashTable) RemoveAll(ctx context.Context, id string) error
// and for some storage it might be nil if memory storage is disabled.
//
// This function is called ever when session starts.
func (s *StorageRedisHashTable) GetSession(ctx context.Context, id string, ttl time.Duration, data *gmap.StrAnyMap) (*gmap.StrAnyMap, error) {
intlog.Printf(ctx, "StorageRedisHashTable.GetSession: %s, %v", id, ttl)
r, err := s.redis.Do(ctx, "EXISTS", s.key(id))
func (s *StorageRedisHashTable) GetSession(ctx context.Context, sessionId string, ttl time.Duration, data *gmap.StrAnyMap) (*gmap.StrAnyMap, error) {
intlog.Printf(ctx, "StorageRedisHashTable.GetSession: %s, %v", sessionId, ttl)
r, err := s.redis.Do(ctx, "EXISTS", s.sessionIdToRedisKey(sessionId))
if err != nil {
return nil, err
}
@ -140,21 +140,21 @@ func (s *StorageRedisHashTable) GetSession(ctx context.Context, id string, ttl t
// SetSession updates the data map for specified session id.
// This function is called ever after session, which is changed dirty, is closed.
// This copy all session data map from memory to storage.
func (s *StorageRedisHashTable) SetSession(ctx context.Context, id string, data *gmap.StrAnyMap, ttl time.Duration) error {
intlog.Printf(ctx, "StorageRedisHashTable.SetSession: %s, %v", id, ttl)
_, err := s.redis.Do(ctx, "EXPIRE", s.key(id), int64(ttl.Seconds()))
func (s *StorageRedisHashTable) SetSession(ctx context.Context, sessionId string, data *gmap.StrAnyMap, ttl time.Duration) error {
intlog.Printf(ctx, "StorageRedisHashTable.SetSession: %s, %v", sessionId, ttl)
_, err := s.redis.Do(ctx, "EXPIRE", s.sessionIdToRedisKey(sessionId), int64(ttl.Seconds()))
return err
}
// UpdateTTL updates the TTL for specified session id.
// This function is called ever after session, which is not dirty, is closed.
// It just adds the session id to the async handling queue.
func (s *StorageRedisHashTable) UpdateTTL(ctx context.Context, id string, ttl time.Duration) error {
intlog.Printf(ctx, "StorageRedisHashTable.UpdateTTL: %s, %v", id, ttl)
_, err := s.redis.Do(ctx, "EXPIRE", s.key(id), int64(ttl.Seconds()))
func (s *StorageRedisHashTable) UpdateTTL(ctx context.Context, sessionId string, ttl time.Duration) error {
intlog.Printf(ctx, "StorageRedisHashTable.UpdateTTL: %s, %v", sessionId, ttl)
_, err := s.redis.Do(ctx, "EXPIRE", s.sessionIdToRedisKey(sessionId), int64(ttl.Seconds()))
return err
}
func (s *StorageRedisHashTable) key(id string) string {
return s.prefix + id
func (s *StorageRedisHashTable) sessionIdToRedisKey(sessionId string) string {
return s.prefix + sessionId
}

View File

@ -54,7 +54,7 @@ func ExampleManager_SetTTL() {
func ExampleSession_Set() {
manager := gsession.New(time.Second, gsession.NewStorageFile())
s := manager.New(gctx.New())
fmt.Println(s.Set("key", "val") == nil)
fmt.Println(s.Set("sessionIdToRedisKey", "val") == nil)
// Output:
// true
@ -72,10 +72,10 @@ func ExampleSession_SetMap() {
func ExampleSession_Remove() {
manager := gsession.New(time.Second, gsession.NewStorageFile())
s1 := manager.New(gctx.New())
fmt.Println(s1.Remove("key"))
fmt.Println(s1.Remove("sessionIdToRedisKey"))
s2 := manager.New(gctx.New(), "Remove")
fmt.Println(s2.Remove("key"))
fmt.Println(s2.Remove("sessionIdToRedisKey"))
// Output:
// <nil>
@ -187,7 +187,7 @@ func ExampleSession_Contains() {
func ExampleStorageFile_SetCryptoKey() {
storage := gsession.NewStorageFile()
storage.SetCryptoKey([]byte("key"))
storage.SetCryptoKey([]byte("sessionIdToRedisKey"))
size, _ := storage.GetSize(gctx.New(), "id")
fmt.Println(size)
@ -223,7 +223,7 @@ func ExampleStorageFile_UpdateTTL() {
func ExampleStorageRedis_Get() {
storage := gsession.NewStorageRedis(&gredis.Redis{})
val, _ := storage.Get(gctx.New(), "id", "key")
val, _ := storage.Get(gctx.New(), "id", "sessionIdToRedisKey")
fmt.Println(val)
// Output:
@ -250,7 +250,7 @@ func ExampleStorageRedis_GetSize() {
func ExampleStorageRedis_Remove() {
storage := gsession.NewStorageRedis(&gredis.Redis{})
err := storage.Remove(gctx.New(), "id", "key")
err := storage.Remove(gctx.New(), "id", "sessionIdToRedisKey")
fmt.Println(err != nil)
// Output:
@ -280,7 +280,7 @@ func ExampleStorageRedis_UpdateTTL() {
func ExampleStorageRedisHashTable_Get() {
storage := gsession.NewStorageRedisHashTable(&gredis.Redis{})
v, err := storage.Get(gctx.New(), "id", "key")
v, err := storage.Get(gctx.New(), "id", "sessionIdToRedisKey")
fmt.Println(v)
fmt.Println(err)
@ -319,7 +319,7 @@ func ExampleStorageRedisHashTable_GetSize() {
func ExampleStorageRedisHashTable_Remove() {
storage := gsession.NewStorageRedisHashTable(&gredis.Redis{})
err := storage.Remove(gctx.New(), "id", "key")
err := storage.Remove(gctx.New(), "id", "sessionIdToRedisKey")
fmt.Println(err)