lspace 0.4 → 0.5

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.
@@ -106,6 +106,7 @@ class LSpace
106
106
  #
107
107
  def around_filter(&filter)
108
108
  around_filters.unshift filter
109
+ self
109
110
  end
110
111
 
111
112
  # Enter this LSpace for the duration of the block
@@ -27,7 +27,7 @@ class Module
27
27
  # Preserve lspace of all blocks passed to this function.
28
28
  #
29
29
  # This wraps both the &block parameter, and also any Procs
30
- # that are passed into the function directly.
30
+ # and Methods that are passed into the function directly.
31
31
  #
32
32
  # If you need more complicated logic (e.g. wrapping Procs
33
33
  # that are passed to a function in a dictionary) you're
@@ -54,7 +54,7 @@ class Module
54
54
  alias_method method_without_lspace, method
55
55
 
56
56
  define_method(method) do |*args, &block|
57
- args.map!{ |a| Proc === a ? a.in_lspace : a }
57
+ args.map!{ |a| (Proc === a || Method === a) ? a.in_lspace : a }
58
58
  block = block.in_lspace if block
59
59
  __send__(method_without_lspace, *args, &block)
60
60
  end
@@ -80,3 +80,22 @@ class Proc
80
80
  LSpace.preserve(&self)
81
81
  end
82
82
  end
83
+
84
+ class Method
85
+ # Preserve LSpace when this method is run. Returns a new Proc, a closure that
86
+ # re-enters the current LSpace when it is called.
87
+ #
88
+ # @example
89
+ # def fire
90
+ # LSpace[:user_id]
91
+ # end
92
+ #
93
+ # todo = method(:fire!).in_lspace
94
+ # todo.call == 2
95
+ # @see LSpace.preserve
96
+ # @return [Proc] A version of self that re-enters LSpace before running
97
+ def in_lspace
98
+ LSpace.preserve(&self)
99
+ end
100
+ end
101
+
@@ -12,6 +12,13 @@ module EventMachine
12
12
  class << self
13
13
  in_lspace :add_timer, :next_tick, :error_handler, :defer, :run, :run_block, :schedule, :fork_reactor
14
14
  in_lspace :add_shutdown_hook if method_defined?(:add_shutdown_hook) # only some versions of EM
15
+
16
+ alias_method :start_server_without_lspace, :start_server
17
+ def start_server(*args, &block)
18
+ s = start_server_without_lspace(*args, &(block ? block.in_lspace : nil))
19
+ @acceptors[s][0].in_lspace
20
+ s
21
+ end
15
22
  end
16
23
 
17
24
  # Many EM APIs (e.g. em-http-request) are based on deferrables. Preserving lspace for
@@ -28,14 +35,40 @@ module EventMachine
28
35
  alias_method :allocate_without_lspace, :allocate
29
36
  end
30
37
 
38
+ # Ensure that instances of this connection are run in the current LSpace
39
+ #
40
+ # This is used by our version of {EM.start_server} to ensure that every
41
+ # instance of the server boots inside the same LSpace.
42
+ #
43
+ # We don't call it on client classes, so they will inherit the active
44
+ # LSpace when the outbound connection is created.
45
+ #
46
+ # @example
47
+ # module Handler
48
+ # def post_init
49
+ # puts LSpace[:error_prefix]
50
+ # end
51
+ # end
52
+ #
53
+ # LSpace.with(:error_prefix => 'handler') do
54
+ # EM::start_server 'localhost', 8080, Handler
55
+ # end
56
+ #
57
+ def self.in_lspace
58
+ @lspace = LSpace.current
59
+ end
60
+
31
61
  # Overridden allocate which sets up a new LSpace.
32
62
  #
33
63
  # Each connection object is run in its own LSpace, which can be
34
64
  # configured by implementing the {Connection#setup_lspace} method.
35
65
  def self.allocate
66
+ lspace = @lspace || LSpace.current
36
67
  allocate_without_lspace.instance_eval do
37
68
  extend EventMachine::LSpacePreserver
38
- LSpace.with do
69
+ # Create a new LSpace per connection so that connections don't
70
+ # effect each other side-ways.
71
+ LSpace.new({}, lspace).enter do
39
72
  setup_lspace
40
73
  @lspace = LSpace.current
41
74
  end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "lspace"
3
- s.version = "0.4"
3
+ s.version = "0.5"
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.author = "Conrad Irwin"
6
6
  s.email = "conrad.irwin@gmail.com"
@@ -76,6 +76,7 @@ describe LSpace do
76
76
  it "should preserve LSpace in all connection callbacks" do
77
77
  $server = []
78
78
  $client = []
79
+ $tick = []
79
80
  server = Module.new do
80
81
  def setup_lspace
81
82
  LSpace[:foo] = :server
@@ -113,19 +114,23 @@ describe LSpace do
113
114
 
114
115
  def unbind
115
116
  $client << [:unbind, LSpace[:foo], LSpace[:bar]]
116
- EM::stop
117
117
  end
118
118
  end
119
119
 
120
- LSpace.with(:bar => :baz) do
121
- EM::run do
120
+ EM::run do
121
+ LSpace.with(:bar => :baz) do
122
122
  EM::start_server '0.0.0.0', 9345, server
123
123
  EM::connect '127.0.0.1', 9345, client
124
+ EM::PeriodicTimer.new(0.1) do
125
+ $tick << [:tick, LSpace[:bar]]
126
+ EM::stop
127
+ end
124
128
  end
125
129
  end
126
130
 
127
131
  $client.should == [[:post_init, :client, :baz], [:receive_data, :client, :baz], [:unbind, :client, :baz]]
128
132
  $server.should == [[:post_init, :server, :baz], [:receive_data, :server, :baz], [:unbind, :server, :baz]]
133
+ $tick.should == [[:tick, :baz]]
129
134
  end
130
135
  end
131
136
  end
metadata CHANGED
@@ -1,128 +1,134 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: lspace
3
- version: !ruby/object:Gem::Version
4
- hash: 3
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.5'
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 4
9
- version: "0.4"
10
6
  platform: ruby
11
- authors:
7
+ authors:
12
8
  - Conrad Irwin
13
9
  autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
-
17
- date: 2012-12-30 00:00:00 Z
18
- dependencies:
19
- - !ruby/object:Gem::Dependency
12
+ date: 2013-02-07 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
20
15
  name: rspec
21
- prerelease: false
22
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
23
17
  none: false
24
- requirements:
25
- - - ">="
26
- - !ruby/object:Gem::Version
27
- hash: 3
28
- segments:
29
- - 0
30
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
31
22
  type: :development
32
- version_requirements: *id001
33
- - !ruby/object:Gem::Dependency
34
- name: pry-rescue
35
23
  prerelease: false
36
- requirement: &id002 !ruby/object:Gem::Requirement
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: pry-rescue
32
+ requirement: !ruby/object:Gem::Requirement
37
33
  none: false
38
- requirements:
39
- - - ">="
40
- - !ruby/object:Gem::Version
41
- hash: 3
42
- segments:
43
- - 0
44
- version: "0"
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
45
38
  type: :development
46
- version_requirements: *id002
47
- - !ruby/object:Gem::Dependency
48
- name: pry-stack_explorer
49
39
  prerelease: false
50
- requirement: &id003 !ruby/object:Gem::Requirement
40
+ version_requirements: !ruby/object:Gem::Requirement
51
41
  none: false
52
- requirements:
53
- - - ">="
54
- - !ruby/object:Gem::Version
55
- hash: 3
56
- segments:
57
- - 0
58
- version: "0"
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: pry-stack_explorer
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
59
54
  type: :development
60
- version_requirements: *id003
61
- - !ruby/object:Gem::Dependency
62
- name: eventmachine
63
55
  prerelease: false
64
- requirement: &id004 !ruby/object:Gem::Requirement
56
+ version_requirements: !ruby/object:Gem::Requirement
65
57
  none: false
66
- requirements:
67
- - - ">="
68
- - !ruby/object:Gem::Version
69
- hash: 3
70
- segments:
71
- - 0
72
- version: "0"
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: eventmachine
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
73
70
  type: :development
74
- version_requirements: *id004
75
- - !ruby/object:Gem::Dependency
76
- name: celluloid
77
71
  prerelease: false
78
- requirement: &id005 !ruby/object:Gem::Requirement
72
+ version_requirements: !ruby/object:Gem::Requirement
79
73
  none: false
80
- requirements:
81
- - - ">="
82
- - !ruby/object:Gem::Version
83
- hash: 3
84
- segments:
85
- - 0
86
- version: "0"
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: celluloid
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
87
86
  type: :development
88
- version_requirements: *id005
89
- - !ruby/object:Gem::Dependency
90
- name: yard
91
87
  prerelease: false
92
- requirement: &id006 !ruby/object:Gem::Requirement
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: yard
96
+ requirement: !ruby/object:Gem::Requirement
93
97
  none: false
94
- requirements:
95
- - - ">="
96
- - !ruby/object:Gem::Version
97
- hash: 3
98
- segments:
99
- - 0
100
- version: "0"
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
101
102
  type: :development
102
- version_requirements: *id006
103
- - !ruby/object:Gem::Dependency
104
- name: redcarpet
105
103
  prerelease: false
106
- requirement: &id007 !ruby/object:Gem::Requirement
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: redcarpet
112
+ requirement: !ruby/object:Gem::Requirement
107
113
  none: false
108
- requirements:
109
- - - ">="
110
- - !ruby/object:Gem::Version
111
- hash: 3
112
- segments:
113
- - 0
114
- version: "0"
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
115
118
  type: :development
116
- version_requirements: *id007
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
117
126
  description: Provides the convenience of global variables, without the safety concerns.
118
127
  email: conrad.irwin@gmail.com
119
128
  executables: []
120
-
121
129
  extensions: []
122
-
123
130
  extra_rdoc_files: []
124
-
125
- files:
131
+ files:
126
132
  - .gitignore
127
133
  - Gemfile
128
134
  - LICENSE.MIT
@@ -144,37 +150,27 @@ files:
144
150
  - spec/spec_helper.rb
145
151
  homepage: http://github.com/ConradIrwin/lspace
146
152
  licenses: []
147
-
148
153
  post_install_message:
149
154
  rdoc_options: []
150
-
151
- require_paths:
155
+ require_paths:
152
156
  - lib
153
- required_ruby_version: !ruby/object:Gem::Requirement
157
+ required_ruby_version: !ruby/object:Gem::Requirement
154
158
  none: false
155
- requirements:
156
- - - ">="
157
- - !ruby/object:Gem::Version
158
- hash: 3
159
- segments:
160
- - 0
161
- version: "0"
162
- required_rubygems_version: !ruby/object:Gem::Requirement
159
+ requirements:
160
+ - - ! '>='
161
+ - !ruby/object:Gem::Version
162
+ version: '0'
163
+ required_rubygems_version: !ruby/object:Gem::Requirement
163
164
  none: false
164
- requirements:
165
- - - ">="
166
- - !ruby/object:Gem::Version
167
- hash: 3
168
- segments:
169
- - 0
170
- version: "0"
165
+ requirements:
166
+ - - ! '>='
167
+ - !ruby/object:Gem::Version
168
+ version: '0'
171
169
  requirements: []
172
-
173
170
  rubyforge_project:
174
171
  rubygems_version: 1.8.24
175
172
  signing_key:
176
173
  specification_version: 3
177
174
  summary: Provides local global storage
178
175
  test_files: []
179
-
180
176
  has_rdoc: