Skip to content

Commit 24be984

Browse files
committed
Global namespacing that applies to all threads
Namespacing is thread-local currently, so it's easy to lose, e.g. when running parallel tests, Capybara tests, or executor pools. Changing that is a major compatibility break, so we introduce a non-thread-local Kredis.global_namespace attribute that behaves as we'd expect. When Kredis.namespace is set, it's appended to the global namespace.
1 parent 8850def commit 24be984

7 files changed

+63
-43
lines changed

lib/kredis/namespace.rb

+21-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,31 @@
11
# frozen_string_literal: true
22

33
module Kredis::Namespace
4-
def namespace=(namespace)
5-
Thread.current[:kredis_namespace] = namespace
6-
end
4+
attr_accessor :global_namespace
75

86
def namespace
9-
Thread.current[:kredis_namespace]
7+
if global_namespace
8+
if value = thread_namespace
9+
"#{global_namespace}:#{value}"
10+
else
11+
global_namespace
12+
end
13+
else
14+
thread_namespace
15+
end
16+
end
17+
18+
def thread_namespace
19+
Thread.current[:kredis_thread_namespace]
1020
end
1121

22+
def thread_namespace=(value)
23+
Thread.current[:kredis_thread_namespace] = value
24+
end
25+
26+
# Backward compatibility
27+
alias_method :namespace=, :thread_namespace=
28+
1229
def namespaced_key(key)
1330
namespace ? "#{namespace}:#{key}" : key
1431
end

lib/kredis/railtie.rb

+2-12
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,8 @@ class Kredis::Railtie < ::Rails::Railtie
55

66
initializer "kredis.testing" do
77
ActiveSupport.on_load(:active_support_test_case) do
8-
$kredis_parallel_worker = nil
9-
parallelize_setup { |worker| $kredis_parallel_worker = worker }
10-
11-
setup do
12-
@original_namespace = Kredis.namespace
13-
Kredis.namespace = [ @original_namespace, :test, $kredis_parallel_worker ].compact.join("-")
14-
end
15-
16-
teardown do
17-
Kredis.clear_all
18-
Kredis.namespace = @original_namespace
19-
end
8+
parallelize_setup { |worker| Kredis.global_namespace = [ Kredis.global_namespace, :test, worker ].compact.join("-") }
9+
teardown { Kredis.clear_all }
2010
end
2111
end
2212

test/attributes_test.rb

+9-9
Original file line numberDiff line numberDiff line change
@@ -120,12 +120,12 @@ class AttributesTest < ActiveSupport::TestCase
120120

121121
test "proxy with custom string key" do
122122
@person.nothing.set "everything"
123-
assert_equal "everything", Kredis.redis.get("something:else")
123+
assert_equal "everything", Kredis.redis.get(Kredis.namespaced_key("something:else"))
124124
end
125125

126126
test "proxy with custom proc key" do
127127
@person.something.set "everything"
128-
assert_equal "everything", Kredis.redis.get("person:8:something")
128+
assert_equal "everything", Kredis.redis.get(Kredis.namespaced_key("person:8:something"))
129129
end
130130

131131
test "list" do
@@ -135,17 +135,17 @@ class AttributesTest < ActiveSupport::TestCase
135135

136136
test "list with custom proc key" do
137137
@person.names_with_custom_key_via_lambda.append(%w[ david kasper ])
138-
assert_equal %w[ david kasper ], Kredis.redis.lrange("person:8:names_customized", 0, -1)
138+
assert_equal %w[ david kasper ], Kredis.redis.lrange(Kredis.namespaced_key("person:8:names_customized"), 0, -1)
139139
end
140140

141141
test "list with custom method key" do
142142
@person.names_with_custom_key_via_method.append(%w[ david kasper ])
143-
assert_equal %w[ david kasper ], Kredis.redis.lrange("some-generated-key", 0, -1)
143+
assert_equal %w[ david kasper ], Kredis.redis.lrange(Kredis.namespaced_key("some-generated-key"), 0, -1)
144144
end
145145

146146
test "list with default proc value" do
147147
assert_equal %w[ Random Jason ], @person.names_with_default_via_lambda.elements
148-
assert_equal %w[ Random Jason ], Kredis.redis.lrange("people:8:names_with_default_via_lambda", 0, -1)
148+
assert_equal %w[ Random Jason ], Kredis.redis.lrange(Kredis.namespaced_key("people:8:names_with_default_via_lambda"), 0, -1)
149149
end
150150

151151
test "unique list" do
@@ -157,7 +157,7 @@ class AttributesTest < ActiveSupport::TestCase
157157

158158
test "unique list with default proc value" do
159159
assert_equal %w[ Random Jason ], @person.skills_with_default_via_lambda.elements
160-
assert_equal %w[ Random Jason ], Kredis.redis.lrange("people:8:skills_with_default_via_lambda", 0, -1)
160+
assert_equal %w[ Random Jason ], Kredis.redis.lrange(Kredis.namespaced_key("people:8:skills_with_default_via_lambda"), 0, -1)
161161
end
162162

163163
test "ordered set" do
@@ -222,7 +222,7 @@ class AttributesTest < ActiveSupport::TestCase
222222
end
223223

224224
test "float with default proc value" do
225-
assert_not_equal 73.2, Kredis.redis.get("people:8:height_with_default_via_lambda")
225+
assert_not_equal 73.2, Kredis.redis.get(Kredis.namespaced_key("people:8:height_with_default_via_lambda"))
226226
assert_equal 73.2, @person.height_with_default_via_lambda.value
227227
assert_equal "73.2", @person.height_with_default_via_lambda.to_s
228228
end
@@ -321,7 +321,7 @@ class AttributesTest < ActiveSupport::TestCase
321321

322322
test "set with default proc value" do
323323
assert_equal [ "Paris" ], @person.vacations_with_default_via_lambda.members
324-
assert_equal [ "Paris" ], Kredis.redis.smembers("people:8:vacations_with_default_via_lambda")
324+
assert_equal [ "Paris" ], Kredis.redis.smembers(Kredis.namespaced_key("people:8:vacations_with_default_via_lambda"))
325325
end
326326

327327
test "json" do
@@ -332,7 +332,7 @@ class AttributesTest < ActiveSupport::TestCase
332332
test "json with default proc value" do
333333
expect = { "height" => 73.2, "weight" => 182.4, "eye_color" => "ha" }
334334
assert_equal expect, @person.settings_with_default_via_lambda.value
335-
assert_equal expect.to_json, Kredis.redis.get("people:8:settings_with_default_via_lambda")
335+
assert_equal expect.to_json, Kredis.redis.get(Kredis.namespaced_key("people:8:settings_with_default_via_lambda"))
336336
end
337337

338338

test/connections_test.rb

+9-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,15 @@
44
require "yaml"
55

66
class ConnectionsTest < ActiveSupport::TestCase
7-
setup { Kredis.connections = {} }
8-
teardown { Kredis.namespace = nil }
7+
setup do
8+
Kredis.connections = {}
9+
@original_global_namespace, Kredis.global_namespace = Kredis.global_namespace, nil
10+
end
11+
12+
teardown do
13+
Kredis.global_namespace = @original_global_namespace
14+
Kredis.namespace = nil
15+
end
916

1017
test "clear all" do
1118
list = Kredis.list "mylist"

test/migration_test.rb

+16-12
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,36 @@
33
require "test_helper"
44

55
class MigrationTest < ActiveSupport::TestCase
6-
setup { @proxy = Kredis.string "new_proxy" }
7-
86
test "migrate_all" do
97
3.times { |index| Kredis.proxy("mykey:#{index}").set "hello there #{index}" }
108

11-
Kredis::Migration.migrate_all("mykey:*") { |key| key.gsub("mykey", "thykey") }
9+
Kredis::Migration.migrate_all(Kredis.namespaced_key("mykey:*")) { |key| "thykey:#{key.split(":").last}" }
1210

1311
3.times do |index|
1412
assert_equal "hello there #{index}", Kredis.proxy("thykey:#{index}").get
1513
end
1614
end
1715

1816
test "migrate" do
17+
@original_global_namespace, Kredis.global_namespace = Kredis.global_namespace, nil
18+
1919
old_proxy = Kredis.string "old_proxy"
2020
old_proxy.set "hello there"
21-
assert_not @proxy.assigned?
2221

23-
Kredis::Migration.migrate from: "old_proxy", to: @proxy.key
24-
assert_equal "hello there", @proxy.value
22+
new_proxy = Kredis.string "new_proxy"
23+
assert_not new_proxy.assigned?
24+
25+
Kredis::Migration.migrate from: Kredis.namespaced_key("old_proxy"), to: "new_proxy"
26+
assert_equal "hello there", new_proxy.value
2527
assert old_proxy.assigned?, "just copying the data"
28+
ensure
29+
Kredis.global_namespace = @original_global_namespace
2630
end
2731

2832
test "migrate with blank keys" do
2933
assert_nothing_raised do
30-
Kredis::Migration.migrate from: "old_key", to: nil
31-
Kredis::Migration.migrate from: "old_key", to: ""
34+
Kredis::Migration.migrate from: Kredis.namespaced_key("old_key"), to: nil
35+
Kredis::Migration.migrate from: Kredis.namespaced_key("old_key"), to: ""
3236
end
3337
end
3438

@@ -37,7 +41,7 @@ class MigrationTest < ActiveSupport::TestCase
3741

3842
Kredis.namespace = "migrate"
3943

40-
Kredis::Migration.migrate from: "key", to: "key"
44+
Kredis::Migration.migrate from: "#{Kredis.global_namespace}:key", to: "key"
4145

4246
assert_equal "x", Kredis.proxy("key").get
4347
ensure
@@ -47,7 +51,7 @@ class MigrationTest < ActiveSupport::TestCase
4751
test "migrate with automatic id extraction" do
4852
Kredis.proxy("mykey:1").set "hey"
4953

50-
Kredis::Migration.migrate_all "mykey:*" do |key, id|
54+
Kredis::Migration.migrate_all Kredis.namespaced_key("mykey:*") do |key, id|
5155
assert_equal 1, id
5256
key
5357
end
@@ -56,15 +60,15 @@ class MigrationTest < ActiveSupport::TestCase
5660
test "delete_all with pattern" do
5761
3.times { |index| Kredis.proxy("mykey:#{index}").set "hello there #{index}" }
5862

59-
Kredis::Migration.delete_all "mykey:*"
63+
Kredis::Migration.delete_all Kredis.namespaced_key("mykey:*")
6064

6165
3.times { |index| assert_nil Kredis.proxy("mykey:#{index}").get }
6266
end
6367

6468
test "delete_all with keys" do
6569
3.times { |index| Kredis.proxy("mykey:#{index}").set "hello there #{index}" }
6670

67-
Kredis::Migration.delete_all(*3.times.map { |index| "mykey:#{index}" })
71+
Kredis::Migration.delete_all(*3.times.map { |index| Kredis.namespaced_key("mykey:#{index}") })
6872

6973
3.times { |index| assert_nil Kredis.proxy("mykey:#{index}").get }
7074
end

test/namespace_test.rb

+4-3
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
require "test_helper"
44

55
class NamespaceTest < ActiveSupport::TestCase
6-
teardown { Kredis.namespace = nil }
6+
teardown { Kredis.thread_namespace = nil }
77

8-
test "list with namespace" do
9-
Kredis.namespace = "test-1"
8+
test "list with per-thread namespace" do
9+
Kredis.thread_namespace = "test-1"
1010
list = Kredis.list "mylist"
1111
list.append "one"
1212
assert_equal [ "one" ], list.elements
1313

14+
# Aliased to thread_namespace= for back-compat
1415
Kredis.namespace = "test-2"
1516
list = Kredis.list "mylist"
1617
assert_equal [], list.elements

test/test_helper.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ def root() Pathname.new(".") end
1919
class ActiveSupport::TestCase
2020
extend Rails::LineFiltering
2121

22-
teardown { Kredis.clear_all }
22+
setup { Kredis.global_namespace = "kredis-test" }
23+
teardown { Kredis.global_namespace = nil; Kredis.clear_all }
2324

2425
class RedisUnavailableProxy
2526
def multi; yield; end

0 commit comments

Comments
 (0)