123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- // Copyright 2014 beego Author. All Rights Reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- // Package memcache for cache provider
- //
- // depend on github.com/bradfitz/gomemcache/memcache
- //
- // go install github.com/bradfitz/gomemcache/memcache
- //
- // Usage:
- // import(
- // _ "github.com/astaxie/beego/cache/memcache"
- // "github.com/astaxie/beego/cache"
- // )
- //
- // bm, err := cache.NewCache("memcache", `{"conn":"127.0.0.1:11211"}`)
- //
- // more docs http://beego.me/docs/module/cache.md
- package memcache
- import (
- "encoding/json"
- "errors"
- "strings"
- "time"
- "github.com/astaxie/beego/cache"
- "github.com/bradfitz/gomemcache/memcache"
- )
- // Cache Memcache adapter.
- type Cache struct {
- conn *memcache.Client
- conninfo []string
- }
- // NewMemCache create new memcache adapter.
- func NewMemCache() cache.Cache {
- return &Cache{}
- }
- // Get get value from memcache.
- func (rc *Cache) Get(key string) interface{} {
- if rc.conn == nil {
- if err := rc.connectInit(); err != nil {
- return err
- }
- }
- if item, err := rc.conn.Get(key); err == nil {
- return item.Value
- }
- return nil
- }
- // GetMulti get value from memcache.
- func (rc *Cache) GetMulti(keys []string) []interface{} {
- size := len(keys)
- var rv []interface{}
- if rc.conn == nil {
- if err := rc.connectInit(); err != nil {
- for i := 0; i < size; i++ {
- rv = append(rv, err)
- }
- return rv
- }
- }
- mv, err := rc.conn.GetMulti(keys)
- if err == nil {
- for _, v := range mv {
- rv = append(rv, v.Value)
- }
- return rv
- }
- for i := 0; i < size; i++ {
- rv = append(rv, err)
- }
- return rv
- }
- // Put put value to memcache.
- func (rc *Cache) Put(key string, val interface{}, timeout time.Duration) error {
- if rc.conn == nil {
- if err := rc.connectInit(); err != nil {
- return err
- }
- }
- item := memcache.Item{Key: key, Expiration: int32(timeout / time.Second)}
- if v, ok := val.([]byte); ok {
- item.Value = v
- } else if str, ok := val.(string); ok {
- item.Value = []byte(str)
- } else {
- return errors.New("val only support string and []byte")
- }
- return rc.conn.Set(&item)
- }
- // Delete delete value in memcache.
- func (rc *Cache) Delete(key string) error {
- if rc.conn == nil {
- if err := rc.connectInit(); err != nil {
- return err
- }
- }
- return rc.conn.Delete(key)
- }
- // Incr increase counter.
- func (rc *Cache) Incr(key string) error {
- if rc.conn == nil {
- if err := rc.connectInit(); err != nil {
- return err
- }
- }
- _, err := rc.conn.Increment(key, 1)
- return err
- }
- // Decr decrease counter.
- func (rc *Cache) Decr(key string) error {
- if rc.conn == nil {
- if err := rc.connectInit(); err != nil {
- return err
- }
- }
- _, err := rc.conn.Decrement(key, 1)
- return err
- }
- // IsExist check value exists in memcache.
- func (rc *Cache) IsExist(key string) bool {
- if rc.conn == nil {
- if err := rc.connectInit(); err != nil {
- return false
- }
- }
- _, err := rc.conn.Get(key)
- if err != nil {
- return false
- }
- return true
- }
- // ClearAll clear all cached in memcache.
- func (rc *Cache) ClearAll() error {
- if rc.conn == nil {
- if err := rc.connectInit(); err != nil {
- return err
- }
- }
- return rc.conn.FlushAll()
- }
- // StartAndGC start memcache adapter.
- // config string is like {"conn":"connection info"}.
- // if connecting error, return.
- func (rc *Cache) StartAndGC(config string) error {
- var cf map[string]string
- json.Unmarshal([]byte(config), &cf)
- if _, ok := cf["conn"]; !ok {
- return errors.New("config has no conn key")
- }
- rc.conninfo = strings.Split(cf["conn"], ";")
- if rc.conn == nil {
- if err := rc.connectInit(); err != nil {
- return err
- }
- }
- return nil
- }
- // connect to memcache and keep the connection.
- func (rc *Cache) connectInit() error {
- rc.conn = memcache.New(rc.conninfo...)
- return nil
- }
- func init() {
- cache.Register("memcache", NewMemCache)
- }
|