improve interface design for gsession.Storage

This commit is contained in:
John
2019-10-28 16:07:01 +08:00
parent baa2cb68de
commit 056d6ebbd9
4 changed files with 45 additions and 16 deletions

View File

@ -39,9 +39,11 @@ func (m *Manager) New(sessionId ...string) *Session {
id = sessionId[0]
}
// NOTE:
// We CANNOT creates and stores it directly to manager
// We CANNOT creates and stores session directly to manager
// as it might be a fake and invalid session id
// which would consumes your memory as much as possible.
//
// We here create a temporary tiny session struct.
return &Session{
id: id,
manager: m,

View File

@ -54,7 +54,7 @@ func (s *Session) init() {
// Set sets key-value pair to this session.
func (s *Session) Set(key string, value interface{}) error {
s.init()
if err := s.manager.storage.Set(s.id, key, value); err != nil {
if err := s.manager.storage.Set(s.id, key, value, s.manager.ttl); err != nil {
if err == ErrorDisabled {
s.data.Set(key, value)
} else {
@ -68,7 +68,7 @@ func (s *Session) Set(key string, value interface{}) error {
// Sets batch sets the session using map.
func (s *Session) Sets(data map[string]interface{}) error {
s.init()
if err := s.manager.storage.SetMap(s.id, data); err != nil {
if err := s.manager.storage.SetMap(s.id, data, s.manager.ttl); err != nil {
if err == ErrorDisabled {
s.data.Sets(data)
} else {
@ -173,12 +173,12 @@ func (s *Session) Close() {
if s.manager.storage != nil {
if s.dirty.Cas(true, false) {
s.data.RLockFunc(func(m map[string]interface{}) {
if err := s.manager.storage.SetSession(s.id, m); err != nil {
if err := s.manager.storage.SetSession(s.id, m, s.manager.ttl); err != nil {
panic(err)
}
})
} else {
if err := s.manager.storage.UpdateTTL(s.id); err != nil {
if err := s.manager.storage.UpdateTTL(s.id, s.manager.ttl); err != nil {
panic(err)
}
}

View File

@ -9,31 +9,45 @@ package gsession
import "time"
type Storage interface {
// New creates a custom session id.
// This function can be used for custom session creation.
New(ttl time.Duration) (id string)
// Get retrieves session value with given key.
// It returns nil if the key does not exist in the session.
Get(id string, key string) interface{}
// GetMap retrieves all key-value pairs as map from storage.
GetMap(id string) map[string]interface{}
// GetSize retrieves the size of key-value pairs from storage.
GetSize(id string) int
// Set sets key-value session pair to the storage.
Set(id string, key string, value interface{}) error
// The parameter <ttl> specifies the TTL for the session id (not for the key-value pair).
Set(id string, key string, value interface{}, ttl time.Duration) error
// SetMap batch sets key-value session pairs with map to the storage.
SetMap(id string, data map[string]interface{}) error
// The parameter <ttl> specifies the TTL for the session id(not for the key-value pair).
SetMap(id string, data map[string]interface{}, ttl time.Duration) error
// Remove deletes key with its value from storage.
Remove(id string, key string) error
// RemoveAll deletes all key-value pairs from storage.
RemoveAll(id string) error
// GetSession returns the session data map for given session id.
// GetSession returns the session data as map for given session id.
// The parameter <ttl> specifies the TTL for this session.
// It returns nil if the TTL is exceeded.
GetSession(id string, ttl time.Duration) map[string]interface{}
// SetSession updates the data map for specified session id.
SetSession(id string, data map[string]interface{}) error
// This function is called ever after session, which is changed dirty, is closed.
// This copy all session data map from memory to storage.
SetSession(id string, data map[string]interface{}, ttl time.Duration) error
// UpdateTTL updates the TTL for specified session id.
UpdateTTL(id string) error
// This function is called ever after session, which is not dirty, is closed.
UpdateTTL(id string, ttl time.Duration) error
}

View File

@ -101,6 +101,12 @@ func (s *StorageFile) sessionFilePath(id string) string {
return gfile.Join(s.path, id)
}
// New creates a session id.
// This function can be used for custom session creation.
func (s *StorageFile) New(ttl time.Duration) (id string) {
return ""
}
// Get retrieves session value with given key.
// It returns nil if the key does not exist in the session.
func (s *StorageFile) Get(id string, key string) interface{} {
@ -118,12 +124,14 @@ func (s *StorageFile) GetSize(id string) int {
}
// Set sets key-value session pair to the storage.
func (s *StorageFile) Set(id string, key string, value interface{}) error {
// The parameter <ttl> specifies the TTL for the session id (not for the key-value pair).
func (s *StorageFile) Set(id string, key string, value interface{}, ttl time.Duration) error {
return ErrorDisabled
}
// SetMap batch sets key-value session pairs with map to the storage.
func (s *StorageFile) SetMap(id string, data map[string]interface{}) error {
// The parameter <ttl> specifies the TTL for the session id(not for the key-value pair).
func (s *StorageFile) SetMap(id string, data map[string]interface{}, ttl time.Duration) error {
return ErrorDisabled
}
@ -137,7 +145,9 @@ func (s *StorageFile) RemoveAll(id string) error {
return ErrorDisabled
}
// GetSession return the session data for given session id.
// GetSession returns the session data as map for given session id.
// The parameter <ttl> specifies the TTL for this session.
// It returns nil if the TTL is exceeded.
func (s *StorageFile) GetSession(id string, ttl time.Duration) map[string]interface{} {
path := s.sessionFilePath(id)
data := gfile.GetBytes(path)
@ -164,8 +174,10 @@ func (s *StorageFile) GetSession(id string, ttl time.Duration) map[string]interf
return nil
}
// SetSession updates the content for session id.
func (s *StorageFile) SetSession(id string, data map[string]interface{}) error {
// 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(id string, data map[string]interface{}, ttl time.Duration) error {
path := s.sessionFilePath(id)
content, err := json.Marshal(data)
if err != nil {
@ -192,8 +204,9 @@ func (s *StorageFile) SetSession(id string, data map[string]interface{}) error {
}
// 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(id string) error {
func (s *StorageFile) UpdateTTL(id string, ttl time.Duration) error {
s.updatingIdSet.Add(id)
return nil
}