Get Redis variable in different package in Golang

huangapple go评论111阅读模式
英文:

Get Redis variable in different package in Golang

问题

我正在使用go-redis/redisgo-redis/cache来缓存Go对象。

  1. import (
  2. "communication/MQ_pkg"
  3. "gopkg.in/go-redis/cache.v3"
  4. "gopkg.in/vmihailenco/msgpack.v2"
  5. )
  6. obj := &VAR_STRUCT{}
  7. Codec.Set(&cache.Item{
  8. Key: key,
  9. Object: obj,
  10. })

在上述代码中,obj是一个具有Go映射(键值对)的结构体。通过上述代码,我设置了一个键并将值保存在其中。这段代码位于common包中。
现在,我想在不导入该包的情况下在不同的包(比如GetRedis_pkg)中访问它。有没有办法可以做到这一点?
并且,我能否通过使用Redis键来访问该结构体中的特定映射?

我导入了gopkg.in/go-redis/cache.v3来在我的代码中使用Redis。

英文:

I'm using go-redis/redis and go-redis/cache to cache Go objects.

  1. import (
  2. "communication/MQ_pkg"
  3. "gopkg.in/go-redis/cache.v3"
  4. "gopkg.in/vmihailenco/msgpack.v2"
  5. )
  6. obj := &VAR_STRUCT{}
  7. Codec.Set(&cache.Item{
  8. Key: key,
  9. Object: obj,
  10. })

where obj is an structure having go maps(key value pair)
By Using above code i am setting a key and saving values into it. This is in package common.
Now i want to access this in different package say GetRedis_pkg without importing pkg. Is there are any way i can do that.
And can i access particular map inside that that structure by any means using redis key
imorted gopkg.in/go-redis/cache.v3 to use redis in my code

答案1

得分: 1

是的,您可以通过使用一个共同的Codec实例来访问相同的映射,用于设置和获取操作。为此,您需要实现一个单例实例生成器。最好是一个线程安全的实现。这样,您将节省大量资源并确保连接的正确性。这对于保持客户端的唯一性以防止错误和节省资源非常重要。

单例编解码器

  1. package singleton
  2. import (
  3. "sync"
  4. "gopkg.in/go-redis/cache.v5"
  5. "gopkg.in/redis.v5"
  6. )
  7. var codec *cache.Codec
  8. var once sync.Once
  9. func GetInstance() *cache.Codec {
  10. once.Do(func() {
  11. client := redis.NewClient(&redis.Options{
  12. Addr: "localhost:6379",
  13. Password: "", // 未设置密码
  14. DB: 0, // 使用默认数据库
  15. })
  16. codec = &cache.Codec{
  17. Redis: client,
  18. Marshal: func(v interface{}) ([]byte, error) {
  19. return msgpack.Marshal(v)
  20. },
  21. Unmarshal: func(b []byte, v interface{}) error {
  22. return msgpack.Unmarshal(b, v)
  23. },
  24. }
  25. })
  26. return codec
  27. }

使用编解码器实例设置键

  1. package setter
  2. import (
  3. "github.com/Me/myapp/singleton"
  4. "sync"
  5. )
  6. func Set(keys []string, vals []SomeObj, wg *sync.WaitGroup) {
  7. for i, k := range keys {
  8. wg.Add(1)
  9. // 单例是线程安全的,可以与goroutine一起使用
  10. go func() {
  11. codec := singleton.GetInstance()
  12. codec.Set(&cache.Item{
  13. Key: k,
  14. Object: vals[i],
  15. Expiration: time.Hour,
  16. })
  17. wg.Done()
  18. }()
  19. }
  20. }

使用相同的编解码器实例获取对象

  1. package getter
  2. import (
  3. "github.com/Me/myapp/singleton"
  4. "sync"
  5. )
  6. func Get(keys []string, wg *sync.WaitGroup) chan SomeObj {
  7. wanted_objs := make(chan *SomeObj)
  8. for i, k := range keys {
  9. wg.Add(1)
  10. // 单例是线程安全的,可以与goroutine一起使用
  11. go func() {
  12. codec := singleton.GetInstance()
  13. wanted := new(SomeObj)
  14. if err := codec.Get(key, wanted); err == nil {
  15. wanted_objs <- wanted
  16. }
  17. }()
  18. }
  19. return wanted_objs
  20. }
英文:

Yes, you can access the same map by using a common Codec instance for both packages and both of set and get operations. For this purposes you need to implement a singleton instance producer. Desirably it should be a thread safe implementation. In this way you will save a lot of resource and guarantee connection correctness. This is significant to keep a client the only to prevent bugs and save resource.

> Client is a Redis client representing a pool of zero or more underlying connections. It's safe for concurrent use by multiple goroutines.

###Singleton codec

  1. package singleton
  2. import (
  3. &quot;sync&quot;
  4. &quot;gopkg.in/go-redis/cache.v5&quot;
  5. &quot;gopkg.in/redis.v5&quot;
  6. )
  7. var codec *cache.Codec
  8. var once sync.Once
  9. func GetInstance() *cache.Codec {
  10. once.Do(func() {
  11. client := redis.NewClient(&amp;redis.Options{
  12. Addr: &quot;localhost:6379&quot;,
  13. Password: &quot;&quot;, // no password set
  14. DB: 0, // use default DB
  15. })
  16. codec = &amp;cache.Codec{
  17. Redis: client,
  18. Marshal: func(v interface{}) ([]byte, error) {
  19. return msgpack.Marshal(v)
  20. },
  21. Unmarshal: func(b []byte, v interface{}) error {
  22. return msgpack.Unmarshal(b, v)
  23. },
  24. }
  25. })
  26. return codec
  27. }

###Set key using codec instance
package setter

  1. import (
  2. &quot;github.com/Me/myapp/singleton&quot;
  3. &quot;sync&quot;
  4. )
  5. func Set(keys []string, vals []SomeObj, wg *sync.WaitGroup){
  6. for i, k := range keys {
  7. wg.Add(1)
  8. // singleton is thread safe and could be used with goroutines
  9. go func() {
  10. codec := single.GetInstance()
  11. codec.Set(&amp;cache.Item{
  12. Key: k,
  13. Object: vals[i],
  14. Expiration: time.Hour,
  15. })
  16. wg.Done()
  17. }()
  18. }
  19. }

Get object using the same codec instance

  1. package getter
  2. import (
  3. &quot;github.com/Me/myapp/singleton&quot;
  4. &quot;sync&quot;
  5. )
  6. func Set(keys []string, wg *sync.WaitGroup) chan SomeObj {
  7. wanted_objs := make(chan *SomeObj)
  8. for i, k := range keys {
  9. wg.Add(1)
  10. // singleton is thread safe and could be used with goroutines
  11. go func() {
  12. codec := singleton.GetInstance()
  13. wanted := new(SomeObj)
  14. if err := codec.Get(key, wanted); err == nil {
  15. wanted_objs &lt;- wanted
  16. }
  17. }()
  18. }
  19. return wanted_objs
  20. }

huangapple
  • 本文由 发表于 2016年12月30日 15:42:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/41392558.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定