Created
February 20, 2019 05:25
-
-
Save bsa7/19b7ddd8d47913fd3d4e26167eff1d78 to your computer and use it in GitHub Desktop.
redis namespaced wrapper for rails
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Api | |
module V2 | |
module ApiHelper | |
## Общий метод генерации ключей для кэша redis | |
def self.redis_key(params) | |
params[:locale] = I18n.locale | |
params_keys = params.keys.map(&:to_s).sort.map(&:to_sym) | |
['.', params_keys.map { |key| "#{key}:#{params[key]}" }.join('&'), '.'].join | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
class ApplicationRecord < ActiveRecord::Base | |
self.abstract_class = true | |
# Расширяет стандартный класс - выдаёт список ключей кэша redis, так или иначе связанных с экземпляром класса | |
def redis_cache_keys | |
redis_key_prefix = "#{self.class.name.gsub(/^.+::/, '').singularize.underscore}_id" | |
[ | |
$redis.keys_namespaced("*#{redis_key_prefix}:#{id}*"), | |
respond_to?(:name) ? $redis.keys_namespaced("*#{redis_key_prefix}:#{name}*") : [] | |
].flatten | |
end | |
# Расширяет стандартный класс - выполняет сброс всех записей кэша redis для определённого экземпляра класса | |
def invalidate_cache | |
redis_cache_keys.each do |redis_key| | |
$redis.del_namespaced(redis_key) | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
redis_url = ENV['REDISCLOUD_URL'] || 'redis://localhost:6379' | |
module RedisCacheMethods | |
def self.key_include_namespace?(key) | |
key[Regexp.new("^#{ENV['REDIS_PREFIX']}-")] ? true : false | |
end | |
def self.key_namespaced(key) | |
if Rails.env == 'test' | |
key_include_namespace?(key) ? "TEST--#{key}" : "TEST--#{ENV['REDIS_PREFIX']}-#{key}" | |
else | |
key_include_namespace?(key) ? key : "#{ENV['REDIS_PREFIX']}-#{key}" | |
end | |
end | |
def del_namespaced(key) | |
redis_key = RedisCacheMethods.key_namespaced(key) | |
del(redis_key) | |
end | |
def get_namespaced(key) | |
redis_key = RedisCacheMethods.key_namespaced(key) | |
get(redis_key) | |
end | |
def set_namespaced(key, value, expires_in: 24.hours) | |
redis_key = RedisCacheMethods.key_namespaced(key) | |
set(redis_key, value) | |
expire(redis_key, expires_in.to_i) | |
end | |
def keys_namespaced(pattern = '*') | |
redis_pattern = RedisCacheMethods.key_namespaced(pattern) | |
keys(pattern) | |
end | |
def fetch(key, expires_in: 24.hours, options: nil, force: false) | |
redis_key = RedisCacheMethods.key_namespaced(key) | |
if block_given? | |
respond = get(redis_key) | |
if respond.nil? || force | |
puts(options[:cache_empty_message]) if options && options[:cache_empty_message] | |
respond = JSON.generate(Proc.new.call) | |
set(redis_key, respond) | |
expire(redis_key, expires_in.to_i) | |
else | |
puts(options[:cache_exist_message]) if options && options[:cache_exist_message] | |
end | |
JSON.parse(respond) | |
end | |
end | |
end | |
$redis = Redis::Namespace.new(ENV['REDIS_PREFIX'], redis: Redis.new(url: redis_url)) | |
$redis.extend(RedisCacheMethods) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Возвращает список id промокодов, использованных пользователем на определённую покупку | |
def user_used_promocode_ids(user_id:, purchase_id:) | |
redis_key = Api::V2::ApiHelper.redis_key({ | |
type: :user_promocode_ids, | |
user_id: user_id, | |
purchase_id: purchase_id, | |
}) | |
# redis_key example: ".locale:ru&purchase_id:100500&type:user_promocode_ids&user_id:11111." | |
$redis.fetch(redis_key, expires_in: Rails.configuration.REDIS.INTERVALS.LONG) do | |
purchase = Purchase.find(purchase_id) | |
user = User.find(user_id) | |
user_promocodes = user.promocodes.where("purchased_till < ?", purchase.created_at) | |
user_promocodes.ids | |
end | |
end | |
def purchase_something(user_id:, promocode_id:, purchase_id:) | |
purchase = Purchase.find(purchase_id) | |
... | |
purchase.invalidate_cache | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment