Skip to content

Instantly share code, notes, and snippets.

@kowsik
Created January 17, 2012 19:49
Show Gist options
  • Save kowsik/1628449 to your computer and use it in GitHub Desktop.
Save kowsik/1628449 to your computer and use it in GitHub Desktop.
Using Redis Transactions with CouchDB
def incr_site_stats engine, stats
# Increment the site:stats counters (in redis). We use 'created_at'
# to checkpoint the time we created these stats
redis.multi do
redis.hsetnx 'site:stats', 'created_at', Time.now.utc.to_string
stats.each_pair do |k, v|
redis.hincrby 'site:stats', k, v.to_i
end
end
# Start the transaction by doing optimistic locking with watch
redis.watch 'site:stats'
site_stats = redis.hgetall 'site:stats'
created_at = Time.parse_utc site_stats['created_at']
elapsed = Time.now.utc.to_i - created_at.utc.to_i
# Save the stats in CouchDB every 5 minutes
if elapsed > 300
ok = redis.multi { redis.del 'site:stats' }
# If the del operation fails, then there was a conflict and someone else
# updated the site:stats hash. Otherwise, increment the counters in CouchDB
if ok
db.update_doc 'stats' do |_doc|
site_stats.each_pair do |k, v|
next if k == 'created_at'
_doc[k] ||= 0
_doc[k] += v.to_i
end
_doc
end
end
else
redis.unwatch
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment