zeevex_threadsafe 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +22 -5
- data/lib/zeevex_threadsafe/synchronized.rb +63 -0
- data/lib/zeevex_threadsafe/version.rb +1 -1
- data/spec/synchronized_spec.rb +10 -0
- data/spec/thread_locals_spec.rb +12 -12
- metadata +82 -79
data/Rakefile
CHANGED
@@ -7,15 +7,19 @@ require 'rspec/core/rake_task'
|
|
7
7
|
RSpec::Core::RakeTask.new(:spec)
|
8
8
|
|
9
9
|
namespace :spec do
|
10
|
+
SPEC_PLATFORMS = ENV.has_key?('SPEC_PLATFORMS') ?
|
11
|
+
ENV['SPEC_PLATFORMS'].split(/ +/) :
|
12
|
+
%w{1.9.3-p448 2.0.0-p247 1.8.7-p374}
|
13
|
+
|
10
14
|
desc "Run on three Rubies"
|
11
15
|
task :platforms do
|
12
|
-
current = %x{
|
16
|
+
# current = %x[rbenv version | awk '{print $1}']
|
13
17
|
|
14
18
|
fail = false
|
15
|
-
|
19
|
+
SPEC_PLATFORMS.each do |version|
|
16
20
|
puts "Switching to #{version}"
|
17
21
|
Bundler.with_clean_env do
|
18
|
-
system %{bash -c '
|
22
|
+
system %{bash -c 'eval "$(rbenv init -)" && rbenv use #{version} && rbenv rehash && ruby -v && bundle exec rake spec'}
|
19
23
|
end
|
20
24
|
if $?.exitstatus != 0
|
21
25
|
fail = true
|
@@ -23,10 +27,23 @@ namespace :spec do
|
|
23
27
|
end
|
24
28
|
end
|
25
29
|
|
26
|
-
system %{rvm #{current}}
|
27
|
-
|
28
30
|
exit (fail ? 1 : 0)
|
29
31
|
end
|
32
|
+
|
33
|
+
desc 'Install gems for all tested rubies'
|
34
|
+
task :platform_setup do
|
35
|
+
SPEC_PLATFORMS.each do |version|
|
36
|
+
puts "Setting up platform #{version}"
|
37
|
+
Bundler.with_clean_env do
|
38
|
+
system %{bash -c 'eval "$(rbenv init -)" && rbenv use #{version} && rbenv rehash && gem install bundler && bundle install'}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
task :repl do
|
46
|
+
sh %q{ bundle exec irb -Ilib -r zeevex_threadsafe/synchronized }
|
30
47
|
end
|
31
48
|
|
32
49
|
task :default => 'spec'
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'zeevex_proxy'
|
2
|
+
require 'thread'
|
3
|
+
|
4
|
+
#
|
5
|
+
# Wraps an object so that method calls to it via the proxy are synchronized.
|
6
|
+
#
|
7
|
+
# These are all equivalent:
|
8
|
+
#
|
9
|
+
# ZeevexThreadsafe::Synchronized.new(orig_object)
|
10
|
+
# ZeevexThreadsafe::Synchronized.wrap(orig_object)
|
11
|
+
# ZeevexThreadsafe.synchronized orig_object
|
12
|
+
#
|
13
|
+
# Each style of invocation returns a new proxy object which wraps
|
14
|
+
# orig_object such that every method invocation *through the proxy*
|
15
|
+
# will be synchronized with a per-object Mutex.
|
16
|
+
#
|
17
|
+
# Each style also accepts an optional second argument which is a Mutex
|
18
|
+
# (or anything that duck-types with Mutex#synchronize). This allows
|
19
|
+
# multiple objects to be synchronized on the same mutex.
|
20
|
+
#
|
21
|
+
# Note that internal method calls within the wrapped object are *not*
|
22
|
+
# synchronized. If any thread can access the wrapped object directly,
|
23
|
+
# then this class will not guarantee thread-safety.
|
24
|
+
#
|
25
|
+
|
26
|
+
module ZeevexThreadsafe
|
27
|
+
class Synchronized < ZeevexProxy::Base
|
28
|
+
def initialize(obj, mutex = Mutex.new)
|
29
|
+
super
|
30
|
+
@__synchronized_mutex = mutex
|
31
|
+
end
|
32
|
+
|
33
|
+
def method_missing(name, *args, &block)
|
34
|
+
@__synchronized_mutex.synchronize do
|
35
|
+
super
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# Run a block within a synchronized block around this object's mutex
|
41
|
+
#
|
42
|
+
def synchronize(&block)
|
43
|
+
@__synchronized_mutex.synchronize do
|
44
|
+
yield
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.wrap(*args)
|
49
|
+
Synchronized.new(*args)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.synchronized(*args)
|
54
|
+
ZeevexThreadsafe::Synchronized.wrap(*args)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
#
|
60
|
+
#
|
61
|
+
#
|
62
|
+
# See also https://github.com/ryanlecompte/synchronizable
|
63
|
+
#
|
data/spec/thread_locals_spec.rb
CHANGED
@@ -104,11 +104,11 @@ describe ZeevexThreadsafe::ThreadLocals do
|
|
104
104
|
|
105
105
|
[:private_var].each do |key|
|
106
106
|
it "should have defined reader for #{key}" do
|
107
|
-
instance.private_methods.should include(key.to_s)
|
107
|
+
instance.private_methods.map(&:to_s).should include(key.to_s)
|
108
108
|
end
|
109
109
|
|
110
110
|
it "should have defined writer for #{key}" do
|
111
|
-
instance.private_methods.should include(key.to_s + "=")
|
111
|
+
instance.private_methods.map(&:to_s).should include(key.to_s + "=")
|
112
112
|
end
|
113
113
|
end
|
114
114
|
end
|
@@ -146,19 +146,19 @@ describe ZeevexThreadsafe::ThreadLocals do
|
|
146
146
|
|
147
147
|
context "visibility" do
|
148
148
|
it "should define methods as public by default" do
|
149
|
-
instance.public_methods.should include("plain", "plain=", "mult1", "mult1=")
|
149
|
+
instance.public_methods.map(&:to_s).should include("plain", "plain=", "mult1", "mult1=")
|
150
150
|
end
|
151
151
|
|
152
152
|
it "should define methods as protected when :visibility => :protected" do
|
153
|
-
instance.protected_methods.should include("protected_var", "protected_var=")
|
153
|
+
instance.protected_methods.map(&:to_s).should include("protected_var", "protected_var=")
|
154
154
|
end
|
155
155
|
|
156
156
|
it "should define methods as private when :visibility => :private" do
|
157
|
-
instance.private_methods.should include("private_var", "private_var=")
|
157
|
+
instance.private_methods.map(&:to_s).should include("private_var", "private_var=")
|
158
158
|
end
|
159
159
|
|
160
160
|
it "should define methods as public when :visibility is not provided, even in a private context" do
|
161
|
-
instance.public_methods.should include("contextually_private_var", "contextually_private_var=")
|
161
|
+
instance.public_methods.map(&:to_s).should include("contextually_private_var", "contextually_private_var=")
|
162
162
|
end
|
163
163
|
end
|
164
164
|
|
@@ -248,11 +248,11 @@ describe ZeevexThreadsafe::ThreadLocals do
|
|
248
248
|
|
249
249
|
[:private_var].each do |key|
|
250
250
|
it "should have defined reader for #{key}" do
|
251
|
-
instance.private_methods.should include(key.to_s)
|
251
|
+
instance.private_methods.map(&:to_s).should include(key.to_s)
|
252
252
|
end
|
253
253
|
|
254
254
|
it "should have defined writer for #{key}" do
|
255
|
-
instance.private_methods.should include(key.to_s + "=")
|
255
|
+
instance.private_methods.map(&:to_s).should include(key.to_s + "=")
|
256
256
|
end
|
257
257
|
end
|
258
258
|
end
|
@@ -292,19 +292,19 @@ describe ZeevexThreadsafe::ThreadLocals do
|
|
292
292
|
|
293
293
|
context "visibility" do
|
294
294
|
it "should define methods as public by default" do
|
295
|
-
instance.public_methods.should include("plain", "plain=", "mult1", "mult1=")
|
295
|
+
instance.public_methods.map(&:to_s).should include("plain", "plain=", "mult1", "mult1=")
|
296
296
|
end
|
297
297
|
|
298
298
|
it "should define methods as protected when :visibility => :protected" do
|
299
|
-
instance.protected_methods.should include("protected_var", "protected_var=")
|
299
|
+
instance.protected_methods.map(&:to_s).should include("protected_var", "protected_var=")
|
300
300
|
end
|
301
301
|
|
302
302
|
it "should define methods as private when :visibility => :private" do
|
303
|
-
instance.private_methods.should include("private_var", "private_var=")
|
303
|
+
instance.private_methods.map(&:to_s).should include("private_var", "private_var=")
|
304
304
|
end
|
305
305
|
|
306
306
|
it "should define methods as public when :visibility is not provided, even in a private context" do
|
307
|
-
instance.public_methods.should include("contextually_private_var", "contextually_private_var=")
|
307
|
+
instance.public_methods.map(&:to_s).should include("contextually_private_var", "contextually_private_var=")
|
308
308
|
end
|
309
309
|
end
|
310
310
|
|
metadata
CHANGED
@@ -1,82 +1,87 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: zeevex_threadsafe
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 1
|
8
|
-
- 0
|
9
|
-
version: 0.1.0
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
5
|
+
prerelease:
|
10
6
|
platform: ruby
|
11
|
-
authors:
|
7
|
+
authors:
|
12
8
|
- Robert Sanders
|
13
9
|
autorequire:
|
14
10
|
bindir: bin
|
15
11
|
cert_chain: []
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
dependencies:
|
20
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2013-10-05 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
21
15
|
name: zeevex_proxy
|
22
|
-
|
23
|
-
|
24
|
-
requirements:
|
25
|
-
- -
|
26
|
-
- !ruby/object:Gem::Version
|
27
|
-
|
28
|
-
- 0
|
29
|
-
version: "0"
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
30
22
|
type: :runtime
|
31
|
-
version_requirements: *id001
|
32
|
-
- !ruby/object:Gem::Dependency
|
33
|
-
name: zeevex_delayed
|
34
23
|
prerelease: false
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: zeevex_delayed
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
42
38
|
type: :runtime
|
43
|
-
version_requirements: *id002
|
44
|
-
- !ruby/object:Gem::Dependency
|
45
|
-
name: rspec
|
46
39
|
prerelease: false
|
47
|
-
|
48
|
-
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
49
51
|
- - ~>
|
50
|
-
- !ruby/object:Gem::Version
|
51
|
-
segments:
|
52
|
-
- 2
|
53
|
-
- 9
|
54
|
-
- 0
|
52
|
+
- !ruby/object:Gem::Version
|
55
53
|
version: 2.9.0
|
56
54
|
type: :development
|
57
|
-
version_requirements: *id003
|
58
|
-
- !ruby/object:Gem::Dependency
|
59
|
-
name: rake
|
60
55
|
prerelease: false
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.9.0
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rake
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
68
70
|
type: :development
|
69
|
-
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
70
78
|
description: Utilities to help in creating thread-safe apps
|
71
|
-
email:
|
79
|
+
email:
|
72
80
|
- robert@zeevex.com
|
73
81
|
executables: []
|
74
|
-
|
75
82
|
extensions: []
|
76
|
-
|
77
83
|
extra_rdoc_files: []
|
78
|
-
|
79
|
-
files:
|
84
|
+
files:
|
80
85
|
- .gitignore
|
81
86
|
- Gemfile
|
82
87
|
- Rakefile
|
@@ -85,42 +90,40 @@ files:
|
|
85
90
|
- lib/zeevex_threadsafe/rails.rb
|
86
91
|
- lib/zeevex_threadsafe/rails/request_globals.rb
|
87
92
|
- lib/zeevex_threadsafe/rails/thread_pool_release.rb
|
93
|
+
- lib/zeevex_threadsafe/synchronized.rb
|
88
94
|
- lib/zeevex_threadsafe/thread_locals.rb
|
89
95
|
- lib/zeevex_threadsafe/thread_safer.rb
|
90
96
|
- lib/zeevex_threadsafe/version.rb
|
91
97
|
- spec/spec_helper.rb
|
98
|
+
- spec/synchronized_spec.rb
|
92
99
|
- spec/thread_locals_spec.rb
|
93
100
|
- zeevex_threadsafe.gemspec
|
94
|
-
has_rdoc: true
|
95
101
|
homepage: http://github.com/zeevex/zeevex_threadsafe
|
96
102
|
licenses: []
|
97
|
-
|
98
103
|
post_install_message:
|
99
104
|
rdoc_options: []
|
100
|
-
|
101
|
-
require_paths:
|
105
|
+
require_paths:
|
102
106
|
- lib
|
103
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
requirements:
|
112
|
-
- -
|
113
|
-
- !ruby/object:Gem::Version
|
114
|
-
|
115
|
-
- 0
|
116
|
-
version: "0"
|
107
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
108
|
+
none: false
|
109
|
+
requirements:
|
110
|
+
- - ! '>='
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
115
|
+
requirements:
|
116
|
+
- - ! '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
117
119
|
requirements: []
|
118
|
-
|
119
120
|
rubyforge_project: zeevex_threadsafe
|
120
|
-
rubygems_version: 1.
|
121
|
+
rubygems_version: 1.8.23
|
121
122
|
signing_key:
|
122
123
|
specification_version: 3
|
123
124
|
summary: Utilities to help in creating thread-safe apps
|
124
|
-
test_files:
|
125
|
+
test_files:
|
125
126
|
- spec/spec_helper.rb
|
127
|
+
- spec/synchronized_spec.rb
|
126
128
|
- spec/thread_locals_spec.rb
|
129
|
+
has_rdoc:
|