You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // Copyright 2013 Beego Authors
  2. // Copyright 2014 The Macaron Authors
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License"): you may
  5. // not use this file except in compliance with the License. You may obtain
  6. // a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. // License for the specific language governing permissions and limitations
  14. // under the License.
  15. // Package cache is a middleware that provides the cache management of Macaron.
  16. package cache
  17. import (
  18. "fmt"
  19. "gopkg.in/macaron.v1"
  20. )
  21. const _VERSION = "0.3.0"
  22. func Version() string {
  23. return _VERSION
  24. }
  25. // Cache is the interface that operates the cache data.
  26. type Cache interface {
  27. // Put puts value into cache with key and expire time.
  28. Put(key string, val interface{}, timeout int64) error
  29. // Get gets cached value by given key.
  30. Get(key string) interface{}
  31. // Delete deletes cached value by given key.
  32. Delete(key string) error
  33. // Incr increases cached int-type value by given key as a counter.
  34. Incr(key string) error
  35. // Decr decreases cached int-type value by given key as a counter.
  36. Decr(key string) error
  37. // IsExist returns true if cached value exists.
  38. IsExist(key string) bool
  39. // Flush deletes all cached data.
  40. Flush() error
  41. // StartAndGC starts GC routine based on config string settings.
  42. StartAndGC(opt Options) error
  43. }
  44. // Options represents a struct for specifying configuration options for the cache middleware.
  45. type Options struct {
  46. // Name of adapter. Default is "memory".
  47. Adapter string
  48. // Adapter configuration, it's corresponding to adapter.
  49. AdapterConfig string
  50. // GC interval time in seconds. Default is 60.
  51. Interval int
  52. // Occupy entire database. Default is false.
  53. OccupyMode bool
  54. // Configuration section name. Default is "cache".
  55. Section string
  56. }
  57. func prepareOptions(options []Options) Options {
  58. var opt Options
  59. if len(options) > 0 {
  60. opt = options[0]
  61. }
  62. if len(opt.Section) == 0 {
  63. opt.Section = "cache"
  64. }
  65. sec := macaron.Config().Section(opt.Section)
  66. if len(opt.Adapter) == 0 {
  67. opt.Adapter = sec.Key("ADAPTER").MustString("memory")
  68. }
  69. if opt.Interval == 0 {
  70. opt.Interval = sec.Key("INTERVAL").MustInt(60)
  71. }
  72. if len(opt.AdapterConfig) == 0 {
  73. opt.AdapterConfig = sec.Key("ADAPTER_CONFIG").MustString("data/caches")
  74. }
  75. return opt
  76. }
  77. // NewCacher creates and returns a new cacher by given adapter name and configuration.
  78. // It panics when given adapter isn't registered and starts GC automatically.
  79. func NewCacher(name string, opt Options) (Cache, error) {
  80. adapter, ok := adapters[name]
  81. if !ok {
  82. return nil, fmt.Errorf("cache: unknown adapter '%s'(forgot to import?)", name)
  83. }
  84. return adapter, adapter.StartAndGC(opt)
  85. }
  86. // Cacher is a middleware that maps a cache.Cache service into the Macaron handler chain.
  87. // An single variadic cache.Options struct can be optionally provided to configure.
  88. func Cacher(options ...Options) macaron.Handler {
  89. opt := prepareOptions(options)
  90. cache, err := NewCacher(opt.Adapter, opt)
  91. if err != nil {
  92. panic(err)
  93. }
  94. return func(ctx *macaron.Context) {
  95. ctx.Map(cache)
  96. }
  97. }
  98. var adapters = make(map[string]Cache)
  99. // Register registers a adapter.
  100. func Register(name string, adapter Cache) {
  101. if adapter == nil {
  102. panic("cache: cannot register adapter with nil value")
  103. }
  104. if _, dup := adapters[name]; dup {
  105. panic(fmt.Errorf("cache: cannot register adapter '%s' twice", name))
  106. }
  107. adapters[name] = adapter
  108. }