limitations under the License.
*/
+/*
+ * This source code is part of the near-RT RIC (RAN Intelligent Controller)
+ * platform project (RICP).
+ */
+
package sdlgo
import (
- "crypto/rand"
- "encoding/base64"
- "errors"
- "fmt"
- "io"
- "reflect"
- "strings"
- "sync"
- "time"
-
"gerrit.o-ran-sc.org/r/ric-plt/sdlgo/internal/sdlgoredis"
+ "time"
)
//SdlInstance provides an API to read, write and modify
//key-value pairs in a given namespace.
+//Deprecated: Will be removed in a future release, please use instead SyncStorage
+//type defined in syncstorage.go.
type SdlInstance struct {
- nameSpace string
- nsPrefix string
- eventSeparator string
- mutex sync.Mutex
- tmp []byte
- iDatabase
+ nameSpace string
+ nsPrefix string
+ storage *SyncStorage
+}
+
+//Database struct is a holder for the internal database instance. Applications
+//can use this exported data type to locally store a reference to database
+//instance returned from NewDabase() function.
+type Database struct {
+ instances []iDatabase
}
//NewDatabase creates a connection to database that will be used
-//as a backend for the key-value storage. The returned value shall
-//be given as a parameter when calling NewKeyValStorage
-func NewDatabase() *sdlgoredis.DB {
- return sdlgoredis.Create()
+//as a backend for the key-value storage. The returned value
+//can be reused between multiple SDL instances in which case each instance
+//is using the same connection.
+//Deprecated: Will be removed in a future release, because there is no need to
+//create a database before NewSyncStorage function is called, database will
+//be created automatically by NewSyncStorage function.
+func NewDatabase() *Database {
+ db := &Database{}
+ for _, v := range sdlgoredis.Create() {
+ db.instances = append(db.instances, v)
+ }
+ return db
}
//NewSdlInstance creates a new sdl instance using the given namespace.
//The database used as a backend is given as a parameter
-func NewSdlInstance(NameSpace string, db iDatabase) *SdlInstance {
+//Deprecated: Will be removed in a future release, please use NewSyncStorage
+//function instead.
+func NewSdlInstance(NameSpace string, db *Database) *SdlInstance {
return &SdlInstance{
- nameSpace: NameSpace,
- nsPrefix: "{" + NameSpace + "},",
- eventSeparator: "___",
- iDatabase: db,
+ nameSpace: NameSpace,
+ nsPrefix: "{" + NameSpace + "},",
+ storage: newSyncStorage(db),
}
}
//callback as quickly as possible. E.g. reading in callback context should be avoided
//and using of Go signals is recommended. Also it should be noted that in case of several
//events received from different channels, callbacks are called in series one by one.
+//
+//Deprecated: Will be removed in a future release, please use the SubscribeChannel
+//receiver function of the SyncStorage type.
func (s *SdlInstance) SubscribeChannel(cb func(string, ...string), channels ...string) error {
- s.SubscribeChannelDB(cb, s.nsPrefix, s.eventSeparator, s.setNamespaceToChannels(channels...)...)
- return nil
+ return s.storage.SubscribeChannel(s.nameSpace, cb, channels...)
}
//UnsubscribeChannel removes subscription from one or several channels.
+//Deprecated: Will be removed in a future release, please use the UnsubscribeChannel
+//receiver function of the SyncStorage type.
func (s *SdlInstance) UnsubscribeChannel(channels ...string) error {
- s.UnsubscribeChannelDB(s.setNamespaceToChannels(channels...)...)
- return nil
+ return s.storage.UnsubscribeChannel(s.nameSpace, channels...)
}
//Close connection to backend database.
+//Deprecated: Will be removed in a future release, please use the Close receiver
+//function of the SyncStorage type.
func (s *SdlInstance) Close() error {
- return s.CloseDB()
-}
-
-func (s *SdlInstance) checkChannelsAndEvents(cmd string, channelsAndEvents []string) error {
- if len(channelsAndEvents)%2 != 0 {
- return fmt.Errorf("%s: Channels and events must be given as pairs", cmd)
- }
- for i, v := range channelsAndEvents {
- if i%2 != 0 {
- if strings.Contains(v, s.eventSeparator) {
- return fmt.Errorf("%s: event %s contains illegal substring (\"%s\")", cmd, v, s.eventSeparator)
- }
- }
- }
- return nil
-}
-func (s *SdlInstance) setNamespaceToChannels(channels ...string) []string {
- var retVal []string
- for _, v := range channels {
- retVal = append(retVal, s.nsPrefix+v)
- }
- return retVal
-}
-
-func (s *SdlInstance) setNamespaceToKeys(pairs ...interface{}) ([]interface{}, error) {
- retVal := make([]interface{}, 0)
- shouldBeKey := true
- for _, v := range pairs {
- reflectType := reflect.TypeOf(v)
- switch reflectType.Kind() {
- case reflect.Map:
- x := reflect.ValueOf(v).MapRange()
- for x.Next() {
- retVal = append(retVal, s.nsPrefix+x.Key().Interface().(string))
- retVal = append(retVal, x.Value().Interface())
- }
- case reflect.Slice:
- if shouldBeKey {
- x := reflect.ValueOf(v)
- if x.Len()%2 != 0 {
- return []interface{}{}, errors.New("Key/value pairs doesn't match")
- }
- for i2 := 0; i2 < x.Len(); i2++ {
- if i2%2 == 0 {
- retVal = append(retVal, s.nsPrefix+x.Index(i2).Interface().(string))
- } else {
- retVal = append(retVal, x.Index(i2).Interface())
- }
- }
- } else {
- if reflectType.Elem().Kind() == reflect.Uint8 {
- retVal = append(retVal, v)
- shouldBeKey = true
- } else {
- return []interface{}{}, errors.New("Key/value pairs doesn't match")
- }
- }
- case reflect.Array:
- if shouldBeKey {
- x := reflect.ValueOf(v)
- if x.Len()%2 != 0 {
- return []interface{}{}, errors.New("Key/value pairs doesn't match")
- }
- for i2 := 0; i2 < x.Len(); i2++ {
- if i2%2 == 0 {
- retVal = append(retVal, s.nsPrefix+x.Index(i2).Interface().(string))
- } else {
- retVal = append(retVal, x.Index(i2).Interface())
- }
- }
- } else {
- if reflectType.Elem().Kind() == reflect.Uint8 {
- retVal = append(retVal, v)
- shouldBeKey = true
- } else {
- return []interface{}{}, errors.New("Key/value pairs doesn't match")
- }
- }
- default:
- if shouldBeKey {
- retVal = append(retVal, s.nsPrefix+v.(string))
- shouldBeKey = false
- } else {
- retVal = append(retVal, v)
- shouldBeKey = true
- }
- }
- }
- if len(retVal)%2 != 0 {
- return []interface{}{}, errors.New("Key/value pairs doesn't match")
- }
- return retVal, nil
-}
-
-func (s *SdlInstance) prepareChannelsAndEvents(channelsAndEvents []string) []string {
- channelEventMap := make(map[string]string)
- for i, v := range channelsAndEvents {
- if i%2 != 0 {
- continue
- }
- _, exists := channelEventMap[v]
- if exists {
- channelEventMap[v] = channelEventMap[v] + s.eventSeparator + channelsAndEvents[i+1]
- } else {
- channelEventMap[v] = channelsAndEvents[i+1]
- }
- }
- retVal := make([]string, 0)
- for k, v := range channelEventMap {
- retVal = append(retVal, s.nsPrefix+k)
- retVal = append(retVal, v)
- }
- return retVal
+ return s.storage.Close()
}
//SetAndPublish function writes data to shared data layer storage and sends an event to
//channel-event pairs.
// E.g. []{"channel1", "event1", "channel2", "event2", "channel1", "event3"}
//will send event1 and event3 to channel1 and event2 to channel2.
+//
+//Deprecated: Will be removed in a future release, please use the SetAndPublish
+//receiver function of the SyncStorage type.
func (s *SdlInstance) SetAndPublish(channelsAndEvents []string, pairs ...interface{}) error {
- keyAndData, err := s.setNamespaceToKeys(pairs...)
- if err != nil {
- return err
- }
- if len(channelsAndEvents) == 0 {
- return s.MSet(keyAndData...)
- }
- if err := s.checkChannelsAndEvents("SetAndPublish", channelsAndEvents); err != nil {
- return err
- }
- channelsAndEventsPrepared := s.prepareChannelsAndEvents(channelsAndEvents)
- return s.MSetMPub(channelsAndEventsPrepared, keyAndData...)
+ return s.storage.SetAndPublish(s.nameSpace, channelsAndEvents, pairs...)
}
//Set function writes data to shared data layer storage. Writing is done
//pairs can be written with one call.
//The key is expected to be string whereas value can be anything, string,
//number, slice array or map
+//Deprecated: Will be removed in a future release, please use the Set receiver
+//function of the SyncStorage type.
func (s *SdlInstance) Set(pairs ...interface{}) error {
- if len(pairs) == 0 {
- return nil
- }
-
- keyAndData, err := s.setNamespaceToKeys(pairs...)
- if err != nil {
- return err
- }
- return s.MSet(keyAndData...)
+ return s.storage.Set(s.nameSpace, pairs...)
}
//Get function atomically reads one or more keys from SDL. The returned map has the
//requested keys as index and data as value. If the requested key is not found
-//from SDL, it's value is nil
+//from SDL, it's value is nil.
+//Deprecated: Will be removed in a future release, please use the Get receiver
+//function of the SyncStorage type.
func (s *SdlInstance) Get(keys []string) (map[string]interface{}, error) {
- m := make(map[string]interface{})
- if len(keys) == 0 {
- return m, nil
- }
-
- var keysWithNs []string
- for _, v := range keys {
- keysWithNs = append(keysWithNs, s.nsPrefix+v)
- }
- val, err := s.MGet(keysWithNs)
- if err != nil {
- return m, err
- }
- for i, v := range val {
- m[keys[i]] = v
- }
- return m, err
+ return s.storage.Get(s.nameSpace, keys)
}
//SetIfAndPublish atomically replaces existing data with newData in SDL if data matches the oldData.
//If replace was done successfully, true will be returned. Also, if publishing was successfull, an event
//is published to a given channel.
+//Deprecated: Will be removed in a future release, please use the SetIfAndPublish
+//receiver function of the SyncStorage type.
func (s *SdlInstance) SetIfAndPublish(channelsAndEvents []string, key string, oldData, newData interface{}) (bool, error) {
- if len(channelsAndEvents) == 0 {
- return s.SetIE(s.nsPrefix+key, oldData, newData)
- }
- if err := s.checkChannelsAndEvents("SetIfAndPublish", channelsAndEvents); err != nil {
- return false, err
- }
- channelsAndEventsPrepared := s.prepareChannelsAndEvents(channelsAndEvents)
- return s.SetIEPub(channelsAndEventsPrepared[0], channelsAndEventsPrepared[1], s.nsPrefix+key, oldData, newData)
+ return s.storage.SetIfAndPublish(s.nameSpace, channelsAndEvents, key, oldData, newData)
}
//SetIf atomically replaces existing data with newData in SDL if data matches the oldData.
//If replace was done successfully, true will be returned.
+//Deprecated: Will be removed in a future release, please use the SetIf receiver
+//function of the SyncStorage type.
func (s *SdlInstance) SetIf(key string, oldData, newData interface{}) (bool, error) {
- return s.SetIE(s.nsPrefix+key, oldData, newData)
+ return s.storage.SetIf(s.nameSpace, key, oldData, newData)
}
//SetIfNotExistsAndPublish conditionally sets the value of a key. If key already exists in SDL,
//then it's value is not changed. Checking the key existence and potential set operation
//is done atomically. If the set operation was done successfully, an event is published to a
//given channel.
+//Deprecated: Will be removed in a future release, please use the SetIfNotExistsAndPublish
+//receiver function of the SyncStorage type.
func (s *SdlInstance) SetIfNotExistsAndPublish(channelsAndEvents []string, key string, data interface{}) (bool, error) {
- if len(channelsAndEvents) == 0 {
- return s.SetNX(s.nsPrefix+key, data, 0)
- }
- if err := s.checkChannelsAndEvents("SetIfNotExistsAndPublish", channelsAndEvents); err != nil {
- return false, err
- }
- channelsAndEventsPrepared := s.prepareChannelsAndEvents(channelsAndEvents)
- return s.SetNXPub(channelsAndEventsPrepared[0], channelsAndEventsPrepared[1], s.nsPrefix+key, data)
+ return s.storage.SetIfNotExistsAndPublish(s.nameSpace, channelsAndEvents, key, data)
}
//SetIfNotExists conditionally sets the value of a key. If key already exists in SDL,
//then it's value is not changed. Checking the key existence and potential set operation
//is done atomically.
+//Deprecated: Will be removed in a future release, please use the SetIfNotExists
+//receiver function of the SyncStorage type.
func (s *SdlInstance) SetIfNotExists(key string, data interface{}) (bool, error) {
- return s.SetNX(s.nsPrefix+key, data, 0)
+ return s.storage.SetIfNotExists(s.nameSpace, key, data)
}
//RemoveAndPublish removes data from SDL. Operation is done atomically, i.e. either all succeeds or fails.
//An event is published into a given channel if remove operation is successfull and
//at least one key is removed (if several keys given). If the given key(s) doesn't exist
//when trying to remove, no event is published.
+//Deprecated: Will be removed in a future release, please use the RemoveAndPublish
+//receiver function of the SyncStorage type.
func (s *SdlInstance) RemoveAndPublish(channelsAndEvents []string, keys []string) error {
- if len(keys) == 0 {
- return nil
- }
-
- var keysWithNs []string
- for _, v := range keys {
- keysWithNs = append(keysWithNs, s.nsPrefix+v)
- }
- if len(channelsAndEvents) == 0 {
- return s.Del(keysWithNs)
- }
- if err := s.checkChannelsAndEvents("RemoveAndPublish", channelsAndEvents); err != nil {
- return err
- }
- channelsAndEventsPrepared := s.prepareChannelsAndEvents(channelsAndEvents)
- return s.DelMPub(channelsAndEventsPrepared, keysWithNs)
+ return s.storage.RemoveAndPublish(s.nameSpace, channelsAndEvents, keys)
}
//Remove data from SDL. Operation is done atomically, i.e. either all succeeds or fails.
+//Deprecated: Will be removed in a future release, please use the Remove receiver
+//function of the SyncStorage type.
func (s *SdlInstance) Remove(keys []string) error {
- if len(keys) == 0 {
- return nil
- }
-
- var keysWithNs []string
- for _, v := range keys {
- keysWithNs = append(keysWithNs, s.nsPrefix+v)
- }
- err := s.Del(keysWithNs)
- return err
+ return s.storage.Remove(s.nameSpace, keys)
}
//RemoveIfAndPublish removes data from SDL conditionally and if remove was done successfully,
//a given event is published to channel. If existing data matches given data,
//key and data are removed from SDL. If remove was done successfully, true is returned.
+//Deprecated: Will be removed in a future release, please use the RemoveIfAndPublish
+//receiver function of the SyncStorage type.
func (s *SdlInstance) RemoveIfAndPublish(channelsAndEvents []string, key string, data interface{}) (bool, error) {
- if len(channelsAndEvents) == 0 {
- return s.DelIE(s.nsPrefix+key, data)
- }
- if err := s.checkChannelsAndEvents("RemoveIfAndPublish", channelsAndEvents); err != nil {
- return false, err
- }
- channelsAndEventsPrepared := s.prepareChannelsAndEvents(channelsAndEvents)
- return s.DelIEPub(channelsAndEventsPrepared[0], channelsAndEventsPrepared[1], s.nsPrefix+key, data)
+ return s.storage.RemoveIfAndPublish(s.nameSpace, channelsAndEvents, key, data)
}
//RemoveIf removes data from SDL conditionally. If existing data matches given data,
//key and data are removed from SDL. If remove was done successfully, true is returned.
+//Deprecated: Will be removed in a future release, please use the RemoveIf receiver
+//function of the SyncStorage type.
func (s *SdlInstance) RemoveIf(key string, data interface{}) (bool, error) {
- status, err := s.DelIE(s.nsPrefix+key, data)
- if err != nil {
- return false, err
- }
- return status, nil
+ return s.storage.RemoveIf(s.nameSpace, key, data)
}
//GetAll returns all keys under the namespace. No prior knowledge about the keys in the
//given namespace exists, thus operation is not guaranteed to be atomic or isolated.
+//Deprecated: Will be removed in a future release, please use the GetAll receiver
+//function of the SyncStorage type.
func (s *SdlInstance) GetAll() ([]string, error) {
- keys, err := s.Keys(s.nsPrefix + "*")
- var retVal []string
- if err != nil {
- return retVal, err
- }
- for _, v := range keys {
- retVal = append(retVal, strings.Split(v, s.nsPrefix)[1])
- }
- return retVal, err
+ return s.storage.GetAll(s.nameSpace)
}
//RemoveAll removes all keys under the namespace. Remove operation is not atomic, thus
//it is not guaranteed that all keys are removed.
+//Deprecated: Will be removed in a future release, please use the RemoveAll receiver
+//function of the SyncStorage type.
func (s *SdlInstance) RemoveAll() error {
- keys, err := s.Keys(s.nsPrefix + "*")
- if err != nil {
- return err
- }
- if (keys != nil) && (len(keys) != 0) {
- err = s.Del(keys)
- }
- return err
+ return s.storage.RemoveAll(s.nameSpace)
}
//RemoveAllAndPublish removes all keys under the namespace and if successfull, it
//will publish an event to given channel. This operation is not atomic, thus it is
//not guaranteed that all keys are removed.
+//Deprecated: Will be removed in a future release, please use the RemoveAllAndPublish
+//receiver function of the SyncStorage type.
func (s *SdlInstance) RemoveAllAndPublish(channelsAndEvents []string) error {
- keys, err := s.Keys(s.nsPrefix + "*")
- if err != nil {
- return err
- }
- if (keys != nil) && (len(keys) != 0) {
- if len(channelsAndEvents) == 0 {
- return s.Del(keys)
- }
- if err := s.checkChannelsAndEvents("RemoveIfAndPublish", channelsAndEvents); err != nil {
- return err
- }
- channelsAndEventsPrepared := s.prepareChannelsAndEvents(channelsAndEvents)
- err = s.DelMPub(channelsAndEventsPrepared, keys)
- }
- return err
+ return s.storage.RemoveAllAndPublish(s.nameSpace, channelsAndEvents)
}
//AddMember adds a new members to a group.
//SDL groups are unordered collections of members where each member is
//unique. It is possible to add the same member several times without the
//need to check if it already exists.
+//Deprecated: Will be removed in a future release, please use the AddMember
+//receiver function of the SyncStorage type.
func (s *SdlInstance) AddMember(group string, member ...interface{}) error {
- return s.SAdd(s.nsPrefix+group, member...)
+ return s.storage.AddMember(s.nameSpace, group, member...)
}
//RemoveMember removes members from a group.
+//Deprecated: Will be removed in a future release, please use the RemoveMember
+//receiver function of the SyncStorage type.
func (s *SdlInstance) RemoveMember(group string, member ...interface{}) error {
- return s.SRem(s.nsPrefix+group, member...)
+ return s.storage.RemoveMember(s.nameSpace, group, member...)
}
//RemoveGroup removes the whole group along with it's members.
+//Deprecated: Will be removed in a future release, please use the RemoveGroup
+//receiver function of the SyncStorage type.
func (s *SdlInstance) RemoveGroup(group string) error {
- return s.Del([]string{s.nsPrefix + group})
+ return s.storage.RemoveGroup(s.nameSpace, group)
}
//GetMembers returns all the members from a group.
+//Deprecated: Will be removed in a future release, please use the GetMembers
+//receiver function of the SyncStorage type.
func (s *SdlInstance) GetMembers(group string) ([]string, error) {
- retVal, err := s.SMembers(s.nsPrefix + group)
- if err != nil {
- return []string{}, err
- }
- return retVal, err
+ return s.storage.GetMembers(s.nameSpace, group)
}
//IsMember returns true if given member is found from a group.
func (s *SdlInstance) IsMember(group string, member interface{}) (bool, error) {
- retVal, err := s.SIsMember(s.nsPrefix+group, member)
- if err != nil {
- return false, err
- }
- return retVal, err
+ return s.storage.IsMember(s.nameSpace, group, member)
}
//GroupSize returns the number of members in a group.
+//Deprecated: Will be removed in a future release, please use the GroupSize
+//receiver function of the SyncStorage type.
func (s *SdlInstance) GroupSize(group string) (int64, error) {
- retVal, err := s.SCard(s.nsPrefix + group)
- if err != nil {
- return 0, err
- }
- return retVal, err
-}
-
-func (s *SdlInstance) randomToken() (string, error) {
- s.mutex.Lock()
- defer s.mutex.Unlock()
-
- if len(s.tmp) == 0 {
- s.tmp = make([]byte, 16)
- }
-
- if _, err := io.ReadFull(rand.Reader, s.tmp); err != nil {
- return "", err
- }
-
- return base64.RawURLEncoding.EncodeToString(s.tmp), nil
+ return s.storage.GroupSize(s.nameSpace, group)
}
//LockResource function is used for locking a resource. The resource lock in
//practice is a key with random value that is set to expire after a time
//period. The value written to key is a random value, thus only the instance
//created a lock, can release it. Resource locks are per namespace.
+//Deprecated: Will be removed in a future release, please use the LockResource
+//receiver function of the SyncStorage type.
func (s *SdlInstance) LockResource(resource string, expiration time.Duration, opt *Options) (*Lock, error) {
- value, err := s.randomToken()
- if err != nil {
- return nil, err
- }
-
- var retryTimer *time.Timer
- for i, attempts := 0, opt.getRetryCount()+1; i < attempts; i++ {
- ok, err := s.SetNX(s.nsPrefix+resource, value, expiration)
- if err != nil {
- return nil, err
- } else if ok {
- return &Lock{s: s, key: resource, value: value}, nil
- }
- if retryTimer == nil {
- retryTimer = time.NewTimer(opt.getRetryWait())
- defer retryTimer.Stop()
- } else {
- retryTimer.Reset(opt.getRetryWait())
- }
-
- select {
- case <-retryTimer.C:
- }
+ l, err := s.storage.LockResource(s.nameSpace, resource, expiration, opt)
+ if l != nil {
+ return &Lock{
+ s: s,
+ storageLock: l,
+ }, err
}
- return nil, errors.New("Lock not obtained")
+ return nil, err
}
//ReleaseResource removes the lock from a resource. If lock is already
//expired or some other instance is keeping the lock (lock taken after expiration),
//an error is returned.
+//Deprecated: Will be removed in a future release, please use the ReleaseResource
+//receiver function of the SyncStorageLock type.
func (l *Lock) ReleaseResource() error {
- ok, err := l.s.DelIE(l.s.nsPrefix+l.key, l.value)
-
- if err != nil {
- return err
- }
- if !ok {
- return errors.New("Lock not held")
- }
- return nil
+ return l.storageLock.ReleaseResource(l.s.nameSpace)
}
//RefreshResource function can be used to set a new expiration time for the
//resource lock (if the lock still exists). The old remaining expiration
//time is overwritten with the given new expiration time.
+//Deprecated: Will be removed in a future release, please use the RefreshResource
+//receiver function of the SyncStorageLock type.
func (l *Lock) RefreshResource(expiration time.Duration) error {
- err := l.s.PExpireIE(l.s.nsPrefix+l.key, l.value, expiration)
- return err
+ return l.storageLock.RefreshResource(l.s.nameSpace, expiration)
}
//CheckResource returns the expiration time left for a resource.
//If the resource doesn't exist, -2 is returned.
+//Deprecated: Will be removed in a future release, please use the CheckResource
+//receiver function of the SyncStorage type.
func (s *SdlInstance) CheckResource(resource string) (time.Duration, error) {
- result, err := s.PTTL(s.nsPrefix + resource)
- if err != nil {
- return 0, err
- }
- if result == time.Duration(-1) {
- return 0, errors.New("invalid resource given, no expiration time attached")
- }
- return result, nil
+ return s.storage.CheckResource(s.nameSpace, resource)
}
//Options struct defines the behaviour for getting the resource lock.
//Lock struct identifies the resource lock instance. Releasing and adjusting the
//expirations are done using the methods defined for this struct.
+//Deprecated: Will be removed in a future release, please use instead the SyncStorageLock
+//type defined in syncstorage.go.
type Lock struct {
- s *SdlInstance
- key string
- value string
-}
-
-type iDatabase interface {
- SubscribeChannelDB(cb sdlgoredis.ChannelNotificationCb, channelPrefix, eventSeparator string, channels ...string)
- UnsubscribeChannelDB(channels ...string)
- MSet(pairs ...interface{}) error
- MSetMPub(channelsAndEvents []string, pairs ...interface{}) error
- MGet(keys []string) ([]interface{}, error)
- CloseDB() error
- Del(keys []string) error
- DelMPub(channelsAndEvents []string, keys []string) error
- Keys(key string) ([]string, error)
- SetIE(key string, oldData, newData interface{}) (bool, error)
- SetIEPub(channel, message, key string, oldData, newData interface{}) (bool, error)
- SetNX(key string, data interface{}, expiration time.Duration) (bool, error)
- SetNXPub(channel, message, key string, data interface{}) (bool, error)
- DelIE(key string, data interface{}) (bool, error)
- DelIEPub(channel, message, key string, data interface{}) (bool, error)
- SAdd(key string, data ...interface{}) error
- SRem(key string, data ...interface{}) error
- SMembers(key string) ([]string, error)
- SIsMember(key string, data interface{}) (bool, error)
- SCard(key string) (int64, error)
- PTTL(key string) (time.Duration, error)
- PExpireIE(key string, data interface{}, expiration time.Duration) error
+ s *SdlInstance
+ storageLock *SyncStorageLock
}