Module: MemcacheCluster
- Extended by:
- MemcacheCluster
- Included in:
- MemcacheCluster
- Defined in:
- lib/droid/heroku/memcache_cluster.rb
Overview
Manages a pool of memcache servers. This class should not be called outside of the reactor - it does not account for asynchronous access to the server list.
Constant Summary collapse
- HEROKU_NAMESPACE =
heroku’s internal memcache namespace
'0Xfa15837Z'
Instance Method Summary collapse
- #add(ip, port) ⇒ Object
-
#attach(droid, file = 'memcached.yml') ⇒ Object
Create listeners for standard memcache cluster related topics.
-
#cache(prefix, options = {}) ⇒ Object
(also: #[])
A MemCache object configured with the given prefix.
- #cache_retry(prefix, opts = {}) ⇒ Object
- #caches ⇒ Object
- #get(prefix, *args) ⇒ Object
-
#heroku ⇒ Object
A MemCache object configured with heroku’s internal memcache namespace.
- #load_from_file(file) ⇒ Object
- #log(type = :debug) ⇒ Object
- #reload_if_stale ⇒ Object
- #remove(host) ⇒ Object
- #servers ⇒ Object
- #set(prefix, *args) ⇒ Object
- #write_to_file ⇒ Object
Instance Method Details
#add(ip, port) ⇒ Object
79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/droid/heroku/memcache_cluster.rb', line 79 def add(ip, port) host = [ip, port].join(':') return if servers.include?(host) log { "#{host} added" } @servers.push host @servers.sort! @caches = {} write_to_file @last_read = Time.now end |
#attach(droid, file = 'memcached.yml') ⇒ Object
Create listeners for standard memcache cluster related topics.
53 54 55 56 57 58 59 |
# File 'lib/droid/heroku/memcache_cluster.rb', line 53 def attach(droid, file='memcached.yml') load_from_file(file) droid.listen4('memcache.up', :queue => "memcache.up.#{LocalStats.this_instance_name}.#$$") { |msg| add(msg['address'], msg['port']) } droid.listen4('instance.down', :queue => "instance.down.#{LocalStats.this_instance_name}.#$$") { |msg| remove(msg['local_ip']) if msg['slot'] == 'memcache' } EM.add_timer(1) { droid.publish('memcache.needed', {}) } end |
#cache(prefix, options = {}) ⇒ Object Also known as: []
A MemCache object configured with the given prefix.
62 63 64 65 |
# File 'lib/droid/heroku/memcache_cluster.rb', line 62 def cache(prefix, ={}) caches[prefix] ||= MemCache.new(servers, .merge(:namespace => prefix)) end |
#cache_retry(prefix, opts = {}) ⇒ Object
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/droid/heroku/memcache_cluster.rb', line 18 def cache_retry(prefix, opts={}) opts[:retries] ||= 5 opts[:delay] ||= 0.5 retried = 0 begin c = cache(prefix) yield c if block_given? rescue MemCache::MemCacheError => e Log.error "#{e.class} -> #{e.message}", :exception => e raise if retried > opts[:retries] retried += 1 sleep opts[:delay] @caches = { } retry end end |
#caches ⇒ Object
69 70 71 72 |
# File 'lib/droid/heroku/memcache_cluster.rb', line 69 def caches reload_if_stale @caches ||= {} end |
#get(prefix, *args) ⇒ Object
44 45 46 47 48 49 50 |
# File 'lib/droid/heroku/memcache_cluster.rb', line 44 def get(prefix, *args) res = nil cache_retry(prefix) do |c| res = c.get(*args) end res end |
#heroku ⇒ Object
A MemCache object configured with heroku’s internal memcache namespace.
14 15 16 |
# File 'lib/droid/heroku/memcache_cluster.rb', line 14 def heroku cache(HEROKU_NAMESPACE) end |
#load_from_file(file) ⇒ Object
110 111 112 113 114 115 |
# File 'lib/droid/heroku/memcache_cluster.rb', line 110 def load_from_file(file) @file = file @last_read = Time.now @servers = YAML.load(File.read(file)) rescue [] @caches = {} end |
#log(type = :debug) ⇒ Object
126 127 128 |
# File 'lib/droid/heroku/memcache_cluster.rb', line 126 def log(type=:debug) Log.send(type, "memcached: #{yield}") end |
#reload_if_stale ⇒ Object
99 100 101 102 103 104 105 106 107 108 |
# File 'lib/droid/heroku/memcache_cluster.rb', line 99 def reload_if_stale if @last_read && (Time.now - @last_read) > 5 && File.mtime(@file) > @last_read log { "server list modified. reloading." } load_from_file(@file) end rescue => boom # ignore errors accessing/reading file. end |
#remove(host) ⇒ Object
91 92 93 94 95 96 97 |
# File 'lib/droid/heroku/memcache_cluster.rb', line 91 def remove(host) if servers.reject!{ |s| s =~ /^#{host}/ } log { "#{host} removed" } caches.clear write_to_file end end |
#servers ⇒ Object
74 75 76 77 |
# File 'lib/droid/heroku/memcache_cluster.rb', line 74 def servers reload_if_stale @servers ||= [] end |
#set(prefix, *args) ⇒ Object
36 37 38 39 40 41 42 |
# File 'lib/droid/heroku/memcache_cluster.rb', line 36 def set(prefix, *args) res = nil cache_retry(prefix) do |c| res = c.set(*args) end res end |
#write_to_file ⇒ Object
117 118 119 120 121 122 123 124 |
# File 'lib/droid/heroku/memcache_cluster.rb', line 117 def write_to_file log { "writing server list: #{@file}" } File.open(@file, 'w') do |f| f.flock(File::LOCK_EX) f.write YAML.dump(@servers) f.flock(File::LOCK_UN) end end |