【发布时间】:2016-03-30 23:11:34
【问题描述】:
我有一些计数器存储在 REDIS 中,这些计数器会根据 customer.rb 中的状态更改进行更新。我需要存储的东西是:
1) 与用户关联的客户数量(用户 has_many customers) 2)具有(使用aasm_state)“开放”或“已声明”状态的客户计数 3)状态为(使用aasm_state)'open
的客户计数每当客户的状态发生变化时,我都会相应地增加/减少 redis 计数器。但是,无论我尝试过什么,计数似乎总是在一段时间后关闭。
我正在使用 Sidekiq,但我不认为这是一个并发问题,因为 REDIS 不应该受到并发问题的影响,对吧?
这是我的计数更新方法:
def reset_stats
if aasm_state_was == 'open' && aasm_state == 'claimed' # open => assigned
# update company and user
user.redis_increment_my_customers_length
company.redis_decrement_open_customers_length
elsif user_id_changed? && aasm_state_was == 'claimed' && aasm_state == 'claimed' # assigned => assigned
# update users (assigner and assignee)
user_was = User.find(user_id_was)
user.redis_increment_my_customers_length
user_was.redis_decrement_my_customers_length
elsif aasm_state_was == 'claimed' && aasm_state == 'closed' # assigned => closed
# update company and user
user_was = User.find(user_id_was)
user_was.redis_decrement_my_customers_length
company.redis_decrement_all_customers_length
elsif aasm_state_was == 'closed' && aasm_state == 'claimed' # closed => assigned
# update company and user
user.redis_increment_my_customers_length
company.redis_increment_all_customers_length
elsif aasm_state_was == 'closed' && aasm_state == 'open' # closed => open
# update company
company.redis_increment_all_customers_length
company.redis_increment_open_customers_length
elsif aasm_state_was == 'open' && aasm_state == 'closed' # open => closed
# update company
company.redis_decrement_all_customers_length
company.redis_decrement_open_customers_length
end
在 user.rb 中:
def redis_length_key
"my_customers_length_for_#{id}"
end
def set_my_customers_length(l)
RED.set(redis_length_key, l)
l.to_i
end
def redis_increment_my_customers_length
RED.get(redis_length_key) ? RED.incr(redis_length_key) : my_customers_length
end
def redis_decrement_my_customers_length
RED.get(redis_length_key) ? RED.decr(redis_length_key) : my_customers_length
end
def my_customers_length
if l = RED.get(redis_length_key)
l.to_i
else
set_my_customers_length(my_customers.length)
end
end
在 company.rb 中:
def open_customers
customers.open
end
def redis_open_length_key
"open_customers_length_for_#{id}"
end
def set_open_customers_length(l)
RED.set(redis_open_length_key, l)
l.to_i
end
def redis_increment_open_customers_length
RED.get(redis_open_length_key) ? RED.incr(redis_open_length_key) : open_customers_length
end
def redis_decrement_open_customers_length
RED.get(redis_open_length_key) ? RED.decr(redis_open_length_key) : open_customers_length
end
def open_customers_length
if l = RED.get(redis_open_length_key)
return l.to_i
else
set_open_customers_length(open_customers.length)
end
end
def redis_all_length_key
"all_customers_length_for_#{id}"
end
def set_all_customers_length(l)
RED.set(redis_all_length_key, l)
l
end
def redis_increment_all_customers_length
RED.get(redis_all_length_key) ? RED.incr(redis_all_length_key) : all_customers_length
end
def redis_decrement_all_customers_length
RED.get(redis_all_length_key) ? RED.decr(redis_all_length_key) : all_customers_length
end
def all_customers_length
if l = RED.get(redis_all_length_key)
l.to_i
else
set_all_customers_length(open_or_claimed_customers.length)
end
end
def open_or_claimed_customers
customers.open_or_claimed
end
对于我想要完成的工作,是否有更好的模式?这非常令人沮丧,因为计数似乎总是在一段时间后变得不正确。请帮忙!
【问题讨论】:
标签: ruby-on-rails redis sidekiq