memcache.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. // Copyright 2014 beego Author. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // Package memcache for cache provider
  15. //
  16. // depend on github.com/bradfitz/gomemcache/memcache
  17. //
  18. // go install github.com/bradfitz/gomemcache/memcache
  19. //
  20. // Usage:
  21. // import(
  22. // _ "github.com/astaxie/beego/cache/memcache"
  23. // "github.com/astaxie/beego/cache"
  24. // )
  25. //
  26. // bm, err := cache.NewCache("memcache", `{"conn":"127.0.0.1:11211"}`)
  27. //
  28. // more docs http://beego.me/docs/module/cache.md
  29. package memcache
  30. import (
  31. "encoding/json"
  32. "errors"
  33. "strings"
  34. "time"
  35. "github.com/astaxie/beego/cache"
  36. "github.com/bradfitz/gomemcache/memcache"
  37. )
  38. // Cache Memcache adapter.
  39. type Cache struct {
  40. conn *memcache.Client
  41. conninfo []string
  42. }
  43. // NewMemCache create new memcache adapter.
  44. func NewMemCache() cache.Cache {
  45. return &Cache{}
  46. }
  47. // Get get value from memcache.
  48. func (rc *Cache) Get(key string) interface{} {
  49. if rc.conn == nil {
  50. if err := rc.connectInit(); err != nil {
  51. return err
  52. }
  53. }
  54. if item, err := rc.conn.Get(key); err == nil {
  55. return item.Value
  56. }
  57. return nil
  58. }
  59. // GetMulti get value from memcache.
  60. func (rc *Cache) GetMulti(keys []string) []interface{} {
  61. size := len(keys)
  62. var rv []interface{}
  63. if rc.conn == nil {
  64. if err := rc.connectInit(); err != nil {
  65. for i := 0; i < size; i++ {
  66. rv = append(rv, err)
  67. }
  68. return rv
  69. }
  70. }
  71. mv, err := rc.conn.GetMulti(keys)
  72. if err == nil {
  73. for _, v := range mv {
  74. rv = append(rv, v.Value)
  75. }
  76. return rv
  77. }
  78. for i := 0; i < size; i++ {
  79. rv = append(rv, err)
  80. }
  81. return rv
  82. }
  83. // Put put value to memcache.
  84. func (rc *Cache) Put(key string, val interface{}, timeout time.Duration) error {
  85. if rc.conn == nil {
  86. if err := rc.connectInit(); err != nil {
  87. return err
  88. }
  89. }
  90. item := memcache.Item{Key: key, Expiration: int32(timeout / time.Second)}
  91. if v, ok := val.([]byte); ok {
  92. item.Value = v
  93. } else if str, ok := val.(string); ok {
  94. item.Value = []byte(str)
  95. } else {
  96. return errors.New("val only support string and []byte")
  97. }
  98. return rc.conn.Set(&item)
  99. }
  100. // Delete delete value in memcache.
  101. func (rc *Cache) Delete(key string) error {
  102. if rc.conn == nil {
  103. if err := rc.connectInit(); err != nil {
  104. return err
  105. }
  106. }
  107. return rc.conn.Delete(key)
  108. }
  109. // Incr increase counter.
  110. func (rc *Cache) Incr(key string) error {
  111. if rc.conn == nil {
  112. if err := rc.connectInit(); err != nil {
  113. return err
  114. }
  115. }
  116. _, err := rc.conn.Increment(key, 1)
  117. return err
  118. }
  119. // Decr decrease counter.
  120. func (rc *Cache) Decr(key string) error {
  121. if rc.conn == nil {
  122. if err := rc.connectInit(); err != nil {
  123. return err
  124. }
  125. }
  126. _, err := rc.conn.Decrement(key, 1)
  127. return err
  128. }
  129. // IsExist check value exists in memcache.
  130. func (rc *Cache) IsExist(key string) bool {
  131. if rc.conn == nil {
  132. if err := rc.connectInit(); err != nil {
  133. return false
  134. }
  135. }
  136. _, err := rc.conn.Get(key)
  137. if err != nil {
  138. return false
  139. }
  140. return true
  141. }
  142. // ClearAll clear all cached in memcache.
  143. func (rc *Cache) ClearAll() error {
  144. if rc.conn == nil {
  145. if err := rc.connectInit(); err != nil {
  146. return err
  147. }
  148. }
  149. return rc.conn.FlushAll()
  150. }
  151. // StartAndGC start memcache adapter.
  152. // config string is like {"conn":"connection info"}.
  153. // if connecting error, return.
  154. func (rc *Cache) StartAndGC(config string) error {
  155. var cf map[string]string
  156. json.Unmarshal([]byte(config), &cf)
  157. if _, ok := cf["conn"]; !ok {
  158. return errors.New("config has no conn key")
  159. }
  160. rc.conninfo = strings.Split(cf["conn"], ";")
  161. if rc.conn == nil {
  162. if err := rc.connectInit(); err != nil {
  163. return err
  164. }
  165. }
  166. return nil
  167. }
  168. // connect to memcache and keep the connection.
  169. func (rc *Cache) connectInit() error {
  170. rc.conn = memcache.New(rc.conninfo...)
  171. return nil
  172. }
  173. func init() {
  174. cache.Register("memcache", NewMemCache)
  175. }