FIX: DistributedCache without namespace mode wasn't working.

This commit is contained in:
Guo Xiang Tan 2017-10-20 20:33:29 +08:00
parent 7bccd47315
commit 57d9830bd2
2 changed files with 54 additions and 10 deletions

View File

@ -10,6 +10,7 @@ require 'base64'
class DistributedCache class DistributedCache
class Manager class Manager
CHANNEL_NAME ||= '/distributed_hash'.freeze
def initialize(message_bus = nil) def initialize(message_bus = nil)
@subscribers = [] @subscribers = []
@ -31,7 +32,7 @@ class DistributedCache
begin begin
current = @subscribers[i] current = @subscribers[i]
next if payload["origin"] == current.identity next if payload["origin"] == current.identity && !Rails.env.test?
next if current.key != payload["hash_key"] next if current.key != payload["hash_key"]
next if payload["discourse_version"] != Discourse.git_version next if payload["discourse_version"] != Discourse.git_version
@ -51,15 +52,11 @@ class DistributedCache
end end
end end
def channel_name
"/distributed_hash".freeze
end
def ensure_subscribe! def ensure_subscribe!
return if @subscribed return if @subscribed
@lock.synchronize do @lock.synchronize do
return if @subscribed return if @subscribed
@message_bus.subscribe(channel_name) do |message| @message_bus.subscribe(CHANNEL_NAME) do |message|
@lock.synchronize do @lock.synchronize do
process_message(message) process_message(message)
end end
@ -72,7 +69,7 @@ class DistributedCache
message[:origin] = hash.identity message[:origin] = hash.identity
message[:hash_key] = hash.key message[:hash_key] = hash.key
message[:discourse_version] = Discourse.git_version message[:discourse_version] = Discourse.git_version
@message_bus.publish(channel_name, message, user_ids: [-1]) @message_bus.publish(CHANNEL_NAME, message, user_ids: [-1])
end end
def set(hash, key, value) def set(hash, key, value)
@ -143,13 +140,12 @@ class DistributedCache
end end
def hash(db = nil) def hash(db = nil)
db ||= begin db =
if @namespace if @namespace
RailsMultisite::ConnectionManagement.current_db db || RailsMultisite::ConnectionManagement.current_db
else else
RailsMultisite::ConnectionManagement::DEFAULT RailsMultisite::ConnectionManagement::DEFAULT
end end
end
@data[db] ||= ThreadSafe::Hash.new @data[db] ||= ThreadSafe::Hash.new
end end

View File

@ -0,0 +1,48 @@
require 'rails_helper'
RSpec.describe 'Multisite SiteSettings' do
let(:conn) { RailsMultisite::ConnectionManagement }
before do
conn.config_filename = "spec/fixtures/multisite/two_dbs.yml"
conn.load_settings!
conn.remove_class_variable(:@@current_db)
end
after do
conn.clear_settings!
[:@@db_spec_cache, :@@host_spec_cache, :@@default_spec].each do |class_variable|
conn.remove_class_variable(class_variable)
end
conn.set_current_db
end
def cache(name, namespace: true)
DistributedCache.new(name, namespace: namespace)
end
context 'without namespace' do
let(:cache1) { cache('test', namespace: false) }
it 'does not leak state across multisite' do
cache1['default'] = true
expect(cache1.hash).to eq('default' => true)
conn.with_connection('second') do
message = MessageBus.track_publish(DistributedCache::Manager::CHANNEL_NAME) do
cache1['second'] = true
end.first
expect(message.data[:hash_key]).to eq('test')
expect(message.data[:op]).to eq(:set)
expect(message.data[:key]).to eq('second')
expect(message.data[:value]).to eq(true)
end
expect(cache1.hash).to eq('default' => true, 'second' => true)
end
end
end