qrpc 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,11 +1,17 @@
1
1
 
2
+ 0.3.0
3
+ * bad json-rpc-object dependency (but noncritical, some special cases
4
+ performance lag only)
5
+ * all public methods from Client moved to Client::Dispatcher
6
+
2
7
  0.2.2 (2011-02-13)
3
8
  * subminor bug corrections
4
9
  * beanstalkd queue now isn't emptified independently of the max
5
- job settings
10
+ job settings
6
11
  * max jobs set to 0 means, it's unlimited
7
12
  * max job settings is now 0 by default
8
13
  * minor performance optimizations
14
+ * hash-utils gem dependency removed
9
15
 
10
16
  0.2.1 (2011-02-06)
11
17
  * missing UUID dependency in gem specification
data/Gemfile CHANGED
@@ -1,7 +1,7 @@
1
1
  source "http://rubygems.org"
2
2
  # Add dependencies required to use your gem here.
3
3
  # Example:
4
- gem "json-rpc-objects", ">= 0.3.1"
4
+ gem "json-rpc-objects", ">= 0.3.3"
5
5
  gem "depq", ">= 0.4"
6
6
  gem "em-jack", ">= 0.1.3"
7
7
  gem "eventmachine", ">= 0.12.10"
@@ -7,12 +7,12 @@ GEM
7
7
  eventmachine
8
8
  eventmachine (0.12.10)
9
9
  git (1.2.5)
10
- hash-utils (0.4.1)
10
+ hash-utils (0.10.0)
11
11
  jeweler (1.5.2)
12
12
  bundler (~> 1.0.0)
13
13
  git (>= 1.2.5)
14
14
  rake
15
- json-rpc-objects (0.3.1)
15
+ json-rpc-objects (0.3.3)
16
16
  addressable (>= 2.2.2)
17
17
  hash-utils (>= 0.3.0)
18
18
  multitype-introspection (>= 0.1.0)
@@ -25,7 +25,7 @@ GEM
25
25
  multitype-introspection (>= 0.1.0)
26
26
  uuid (2.3.1)
27
27
  macaddr (~> 1.0)
28
- yajl-ruby (0.7.9)
28
+ yajl-ruby (0.8.1)
29
29
 
30
30
  PLATFORMS
31
31
  ruby
@@ -36,5 +36,5 @@ DEPENDENCIES
36
36
  em-jack (>= 0.1.3)
37
37
  eventmachine (>= 0.12.10)
38
38
  jeweler (~> 1.5.2)
39
- json-rpc-objects (>= 0.3.1)
39
+ json-rpc-objects (>= 0.3.3)
40
40
  uuid (>= 2.3.1)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.2
1
+ 0.3.0
@@ -1,9 +1,5 @@
1
1
  # encoding: utf-8
2
- require "em-jack"
3
- require "uuid"
4
- require "qrpc/general"
5
- require "qrpc/client/job"
6
- require "json-rpc-objects/response"
2
+ require "qrpc/client/dispatcher"
7
3
 
8
4
  ##
9
5
  # General QRPC module.
@@ -13,59 +9,24 @@ module QRPC
13
9
 
14
10
  ##
15
11
  # Queue RPC client.
12
+ #
13
+ # @note Since 0.3.0, all non-system methods was moved to
14
+ # {Dispatcher} module for maximal avoiding the user API
15
+ # name conflicts.
16
16
  # @since 0.2.0
17
17
  #
18
18
 
19
19
  class Client
20
20
 
21
21
  ##
22
- # Holds locator of the target queue.
23
- #
24
-
25
- @locator
26
-
27
- ##
28
- # Holds client session ID.
29
- #
30
-
31
- @id
32
-
33
- ##
34
- # Holds input queue name.
35
- #
36
-
37
- @input_name
38
-
39
- ##
40
- # Holds input queue instance.
41
- #
42
-
43
- @input_queue
44
-
45
- ##
46
- # Holds output queue name.
47
- #
48
-
49
- @output_name
50
-
51
- ##
52
- # Holds output queue instance.
22
+ # Holds working dispatcher.
53
23
  #
54
-
55
- @output_queue
56
-
57
- ##
58
- # Indicates, results pooling is ran.
24
+ # @return [Dispatcher]
25
+ # @since 0.3.0
59
26
  #
60
27
 
61
- @pooling
62
-
63
- ##
64
- # Holds clients for finalizing.
65
- #
66
-
67
- @@clients = { }
68
-
28
+ attr_accessor :dispatcher
29
+ @dispatcher
69
30
 
70
31
  ##
71
32
  # Constructor.
@@ -73,46 +34,9 @@ module QRPC
73
34
  #
74
35
 
75
36
  def initialize(locator)
76
- @locator = locator
77
- @pooling = false
78
- @jobs = { }
79
-
80
- # Destructor
81
- ObjectSpace.define_finalizer(self, self.class.method(:finalize).to_proc)
82
- @@clients[self.object_id] = self
37
+ @dispatcher = QRPC::Client::Dispatcher::new(locator)
83
38
  end
84
-
85
- ##
86
- # Finalizer handler.
87
- # @param [Integer] id id of finalized instance
88
- #
89
-
90
- def self.finalize(id)
91
- if @@clients.has_key? id
92
- @@clients[id].finalize!
93
- end
94
- end
95
-
96
- ##
97
- # Destructor.
98
- #
99
-
100
- def finalize!
101
- if not @input_queue.nil?
102
- @input_queue.watch("default") do
103
- @input_queue.ignore(@input_name.to_s) do
104
- @input_queue.close
105
- end
106
- end
107
- end
108
-
109
- if not @output_queue.nil?
110
- @output_queue.use("default") do
111
- @output_queue.close
112
- end
113
- end
114
- end
115
-
39
+
116
40
  ##
117
41
  # Handles call to RPC. (*********)
118
42
  #
@@ -125,153 +49,8 @@ module QRPC
125
49
  #
126
50
 
127
51
  def method_missing(name, *args, &block)
128
- self.put(self.create_job(name, args, &block))
52
+ @dispatcher.put(@dispatcher.create_job(name, args, &block))
129
53
  end
130
-
131
- ##
132
- # Creates job associated to this client session.
133
- #
134
- # @param [Symbol] name name of the method of the job
135
- # @param [Array] args arguments of the method call
136
- # @param [Integer] priority job priority
137
- # @param [Proc] block result returning callback
138
- # @return [QRPC::Client::Job] new job
139
- #
140
-
141
- def create_job(name, args, priority = QRPC::DEFAULT_PRIORITY, &block)
142
- Client::Job::new(self.id, name, args, priority, &block)
143
- end
144
-
145
- ##
146
- # Puts job to client.
147
- # @param [QRPC::Client::Job] job job for put to output queue
148
-
149
- def put(job)
150
- if not job.notification?
151
- @jobs[job.id] = job
152
- end
153
-
154
- self.output_queue do |queue|
155
- queue.put(job.to_json)
156
- end
157
-
158
- if (not @pooling) and (@jobs.length > 0)
159
- self.pool!
160
- end
161
- end
162
-
163
- ##
164
- # Starts input (results) pooling.
165
- #
166
-
167
- def pool!
168
-
169
- # Results processing logic
170
- processor = Proc::new do |job|
171
- response = JsonRpcObjects::Response::parse(job.body)
172
- id = response.id.to_sym
173
- job.delete()
174
-
175
- if @jobs.include? id
176
- @jobs[id].assign_result(response)
177
- end
178
-
179
- @jobs.delete(id)
180
- end
181
-
182
- # Runs processor for each job
183
- parent = self
184
- worker = EM.spawn do
185
- parent.input_queue { |q| q.each_job(&processor) }
186
- end
187
-
188
- ##
189
-
190
- worker.run
191
- @pooling = true
192
-
193
- end
194
-
195
- ##
196
- # Returns input name.
197
- # @return [Symbol] input queue name
198
- #
199
-
200
- def input_name
201
- if @input_name.nil?
202
- @input_name = (QRPC::QUEUE_PREFIX.dup << "-" << self.id.to_s << "-" << QRPC::QUEUE_POSTFIX_OUTPUT).to_sym
203
- end
204
-
205
- return @input_name
206
- end
207
-
208
- ##
209
- # Returns input queue.
210
- # @param [Proc] block block to which will be input queue given
211
- #
212
-
213
- def input_queue(&block)
214
- if @input_queue.nil?
215
- @input_queue = EMJack::Connection::new(:host => @locator.host, :port => @locator.port)
216
- @input_queue.watch(self.input_name.to_s) do
217
- @input_queue.ignore("default") do
218
-
219
- # Results pooler error handler
220
- @input_queue.on_error do |error|
221
- raise ::Exception::new("Beanstalk error: " << error.to_s)
222
- end
223
-
224
- # Returns
225
- block.call(@input_queue)
226
-
227
- end
228
- end
229
- else
230
- block.call(@input_queue)
231
- end
232
- end
233
-
234
- ##
235
- # Returns output name.
236
- # @return [Symbol] output queue name
237
- #
238
-
239
- def output_name
240
- if @output_name.nil?
241
- @output_name = (QRPC::QUEUE_PREFIX.dup << "-" << @locator.queue << "-" << QRPC::QUEUE_POSTFIX_INPUT).to_sym
242
- end
243
-
244
- return @output_name
245
- end
246
-
247
- ##
248
- # Returns output queue.
249
- # @param [Proc] block block to which will be output queue given
250
- #
251
-
252
- def output_queue(&block)
253
- if @output_queue.nil?
254
- @output_queue = EMJack::Connection::new(:host => @locator.host, :port => @locator.port)
255
- @output_queue.use(self.output_name.to_s) do
256
- block.call(@output_queue)
257
- end
258
- else
259
- block.call(@output_queue)
260
- end
261
- end
262
-
263
- ##
264
- # Returns client (or maybe session is better) ID.
265
- # @return [Symbol] client (session) ID
266
- #
267
-
268
- def id
269
- if @id.nil?
270
- @id = UUID.generate.to_sym
271
- end
272
-
273
- return @id
274
- end
275
-
54
+
276
55
  end
277
56
  end
@@ -0,0 +1,275 @@
1
+ # encoding: utf-8
2
+ require "em-jack"
3
+ require "uuid"
4
+ require "qrpc/general"
5
+ require "qrpc/client/job"
6
+ require "json-rpc-objects/response"
7
+
8
+ ##
9
+ # General QRPC module.
10
+ #
11
+
12
+ module QRPC
13
+
14
+ ##
15
+ # Queue RPC client.
16
+ #
17
+ # @note Since 0.3.0, all non-system methods was moved to the
18
+ # {Dispatcher} module for maximal avoiding the user API
19
+ # name conflicts.
20
+ # @since 0.2.0
21
+ #
22
+
23
+ class Client
24
+
25
+ ##
26
+ # Queue RPC client dispatcher (worker).
27
+ # @since 0.3.0
28
+ #
29
+
30
+ class Dispatcher
31
+
32
+ ##
33
+ # Holds locator of the target queue.
34
+ #
35
+
36
+ @locator
37
+
38
+ ##
39
+ # Holds client session ID.
40
+ #
41
+
42
+ @id
43
+
44
+ ##
45
+ # Holds input queue name.
46
+ #
47
+
48
+ @input_name
49
+
50
+ ##
51
+ # Holds input queue instance.
52
+ #
53
+
54
+ @input_queue
55
+
56
+ ##
57
+ # Holds output queue name.
58
+ #
59
+
60
+ @output_name
61
+
62
+ ##
63
+ # Holds output queue instance.
64
+ #
65
+
66
+ @output_queue
67
+
68
+ ##
69
+ # Indicates, results pooling is ran.
70
+ #
71
+
72
+ @pooling
73
+
74
+ ##
75
+ # Holds clients for finalizing.
76
+ #
77
+
78
+ @@clients = { }
79
+
80
+
81
+ ##
82
+ # Constructor.
83
+ # @param [QRPC::Locator] locator of the output queue
84
+ #
85
+
86
+ def initialize(locator)
87
+ @locator = locator
88
+ @pooling = false
89
+ @jobs = { }
90
+
91
+ # Destructor
92
+ ObjectSpace.define_finalizer(self, self.class.method(:finalize).to_proc)
93
+ @@clients[self.object_id] = self
94
+ end
95
+
96
+ ##
97
+ # Finalizer handler.
98
+ # @param [Integer] id id of finalized instance
99
+ #
100
+
101
+ def self.finalize(id)
102
+ if @@clients.has_key? id
103
+ @@clients[id].finalize!
104
+ end
105
+ end
106
+
107
+ ##
108
+ # Destructor.
109
+ #
110
+
111
+ def finalize!
112
+ if not @input_queue.nil?
113
+ @input_queue.watch("default") do
114
+ @input_queue.ignore(@input_name.to_s) do
115
+ @input_queue.close
116
+ end
117
+ end
118
+ end
119
+
120
+ if not @output_queue.nil?
121
+ @output_queue.use("default") do
122
+ @output_queue.close
123
+ end
124
+ end
125
+ end
126
+
127
+ ##
128
+ # Creates job associated to this client session.
129
+ #
130
+ # @param [Symbol] name name of the method of the job
131
+ # @param [Array] args arguments of the method call
132
+ # @param [Integer] priority job priority
133
+ # @param [Proc] block result returning callback
134
+ # @return [QRPC::Client::Job] new job
135
+ #
136
+
137
+ def create_job(name, args, priority = QRPC::DEFAULT_PRIORITY, &block)
138
+ Client::Job::new(self.id, name, args, priority, &block)
139
+ end
140
+
141
+ ##
142
+ # Puts job to client.
143
+ # @param [QRPC::Client::Job] job job for put to output queue
144
+
145
+ def put(job)
146
+ if not job.notification?
147
+ @jobs[job.id] = job
148
+ end
149
+
150
+ self.output_queue do |queue|
151
+ queue.put(job.to_json)
152
+ end
153
+
154
+ if (not @pooling) and (@jobs.length > 0)
155
+ self.pool!
156
+ end
157
+ end
158
+
159
+ ##
160
+ # Starts input (results) pooling.
161
+ #
162
+
163
+ def pool!
164
+
165
+ # Results processing logic
166
+ processor = Proc::new do |job|
167
+ response = JsonRpcObjects::Response::parse(job.body)
168
+ id = response.id.to_sym
169
+ job.delete()
170
+
171
+ if @jobs.include? id
172
+ @jobs[id].assign_result(response)
173
+ end
174
+
175
+ @jobs.delete(id)
176
+ end
177
+
178
+ # Runs processor for each job
179
+ parent = self
180
+ worker = EM.spawn do
181
+ parent.input_queue { |q| q.each_job(&processor) }
182
+ end
183
+
184
+ ##
185
+
186
+ worker.run
187
+ @pooling = true
188
+
189
+ end
190
+
191
+ ##
192
+ # Returns input name.
193
+ # @return [Symbol] input queue name
194
+ #
195
+
196
+ def input_name
197
+ if @input_name.nil?
198
+ @input_name = (QRPC::QUEUE_PREFIX.dup << "-" << self.id.to_s << "-" << QRPC::QUEUE_POSTFIX_OUTPUT).to_sym
199
+ end
200
+
201
+ return @input_name
202
+ end
203
+
204
+ ##
205
+ # Returns input queue.
206
+ # @param [Proc] block block to which will be input queue given
207
+ #
208
+
209
+ def input_queue(&block)
210
+ if @input_queue.nil?
211
+ @input_queue = EMJack::Connection::new(:host => @locator.host, :port => @locator.port)
212
+ @input_queue.watch(self.input_name.to_s) do
213
+ @input_queue.ignore("default") do
214
+
215
+ # Results pooler error handler
216
+ @input_queue.on_error do |error|
217
+ raise ::Exception::new("Beanstalk error: " << error.to_s)
218
+ end
219
+
220
+ # Returns
221
+ block.call(@input_queue)
222
+
223
+ end
224
+ end
225
+ else
226
+ block.call(@input_queue)
227
+ end
228
+ end
229
+
230
+ ##
231
+ # Returns output name.
232
+ # @return [Symbol] output queue name
233
+ #
234
+
235
+ def output_name
236
+ if @output_name.nil?
237
+ @output_name = (QRPC::QUEUE_PREFIX.dup << "-" << @locator.queue << "-" << QRPC::QUEUE_POSTFIX_INPUT).to_sym
238
+ end
239
+
240
+ return @output_name
241
+ end
242
+
243
+ ##
244
+ # Returns output queue.
245
+ # @param [Proc] block block to which will be output queue given
246
+ #
247
+
248
+ def output_queue(&block)
249
+ if @output_queue.nil?
250
+ @output_queue = EMJack::Connection::new(:host => @locator.host, :port => @locator.port)
251
+ @output_queue.use(self.output_name.to_s) do
252
+ block.call(@output_queue)
253
+ end
254
+ else
255
+ block.call(@output_queue)
256
+ end
257
+ end
258
+
259
+ ##
260
+ # Returns client (or maybe session is better) ID.
261
+ # @return [Symbol] client (session) ID
262
+ #
263
+
264
+ def id
265
+ if @id.nil?
266
+ @id = UUID.generate.to_sym
267
+ end
268
+
269
+ return @id
270
+ end
271
+
272
+ end
273
+
274
+ end
275
+ end
@@ -10,6 +10,11 @@ module QRPC
10
10
  ##
11
11
  # Queue RPC client.
12
12
  #
13
+ # @note Since 0.3.0, all non-system methods was moved to the
14
+ # {Dispatcher} module for maximal avoiding the user API
15
+ # name conflicts.
16
+ # @since 0.2.0
17
+ #
13
18
 
14
19
  class Client
15
20
 
@@ -13,6 +13,11 @@ module QRPC
13
13
  ##
14
14
  # Queue RPC client.
15
15
  #
16
+ # @note Since 0.3.0, all non-system methods was moved to the
17
+ # {Dispatcher} module for maximal avoiding the user API
18
+ # name conflicts.
19
+ # @since 0.2.0
20
+ #
16
21
 
17
22
  class Client
18
23
 
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{qrpc}
8
- s.version = "0.2.2"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Martin Kozák"]
12
- s.date = %q{2011-02-13}
12
+ s.date = %q{2011-02-27}
13
13
  s.email = %q{martinkozak@martinkozak.net}
14
14
  s.extra_rdoc_files = [
15
15
  "LICENSE.txt",
@@ -26,6 +26,7 @@ Gem::Specification.new do |s|
26
26
  "TODO.md",
27
27
  "VERSION",
28
28
  "lib/qrpc/client.rb",
29
+ "lib/qrpc/client/dispatcher.rb",
29
30
  "lib/qrpc/client/exception.rb",
30
31
  "lib/qrpc/client/job.rb",
31
32
  "lib/qrpc/general.rb",
@@ -43,14 +44,14 @@ Gem::Specification.new do |s|
43
44
  s.homepage = %q{http://github.com/martinkozak/qrpc}
44
45
  s.licenses = ["MIT"]
45
46
  s.require_paths = ["lib"]
46
- s.rubygems_version = %q{1.5.2}
47
+ s.rubygems_version = %q{1.5.3}
47
48
  s.summary = %q{Queued JSON-RPC client and server. Works as normal RPC server, but through queue interface, so allows highly scalable, distributed and asynchronous remote API implementation and fast data processing. It's based on eventmachine and beanstalkd, so it's fast and thread safe.}
48
49
 
49
50
  if s.respond_to? :specification_version then
50
51
  s.specification_version = 3
51
52
 
52
53
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
53
- s.add_runtime_dependency(%q<json-rpc-objects>, [">= 0.3.1"])
54
+ s.add_runtime_dependency(%q<json-rpc-objects>, [">= 0.3.3"])
54
55
  s.add_runtime_dependency(%q<depq>, [">= 0.4"])
55
56
  s.add_runtime_dependency(%q<em-jack>, [">= 0.1.3"])
56
57
  s.add_runtime_dependency(%q<eventmachine>, [">= 0.12.10"])
@@ -58,7 +59,7 @@ Gem::Specification.new do |s|
58
59
  s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
59
60
  s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
60
61
  else
61
- s.add_dependency(%q<json-rpc-objects>, [">= 0.3.1"])
62
+ s.add_dependency(%q<json-rpc-objects>, [">= 0.3.3"])
62
63
  s.add_dependency(%q<depq>, [">= 0.4"])
63
64
  s.add_dependency(%q<em-jack>, [">= 0.1.3"])
64
65
  s.add_dependency(%q<eventmachine>, [">= 0.12.10"])
@@ -67,7 +68,7 @@ Gem::Specification.new do |s|
67
68
  s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
68
69
  end
69
70
  else
70
- s.add_dependency(%q<json-rpc-objects>, [">= 0.3.1"])
71
+ s.add_dependency(%q<json-rpc-objects>, [">= 0.3.3"])
71
72
  s.add_dependency(%q<depq>, [">= 0.4"])
72
73
  s.add_dependency(%q<em-jack>, [">= 0.1.3"])
73
74
  s.add_dependency(%q<eventmachine>, [">= 0.12.10"])
@@ -5,6 +5,7 @@ require "qrpc/client"
5
5
  require "qrpc/locator"
6
6
  require "eventmachine"
7
7
 
8
+ =begin
8
9
  EM::run do
9
10
  client = QRPC::Client::new QRPC::Locator::new :test
10
11
  # puts client.inspect
@@ -29,8 +30,8 @@ EM::run do
29
30
  # puts i
30
31
  # end
31
32
  end
33
+ =end
32
34
 
33
- =begin
34
35
  require "beanstalk-client"
35
36
  require "json-rpc-objects/request"
36
37
 
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: qrpc
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.2.2
5
+ version: 0.3.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - "Martin Koz\xC3\xA1k"
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-02-13 00:00:00 +01:00
13
+ date: 2011-02-27 00:00:00 +01:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -20,7 +20,7 @@ dependencies:
20
20
  requirements:
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: 0.3.1
23
+ version: 0.3.3
24
24
  type: :runtime
25
25
  prerelease: false
26
26
  version_requirements: *id001
@@ -110,6 +110,7 @@ files:
110
110
  - TODO.md
111
111
  - VERSION
112
112
  - lib/qrpc/client.rb
113
+ - lib/qrpc/client/dispatcher.rb
113
114
  - lib/qrpc/client/exception.rb
114
115
  - lib/qrpc/client/job.rb
115
116
  - lib/qrpc/general.rb
@@ -137,7 +138,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
137
138
  requirements:
138
139
  - - ">="
139
140
  - !ruby/object:Gem::Version
140
- hash: -1069714967795243013
141
+ hash: 3226549344663935537
141
142
  segments:
142
143
  - 0
143
144
  version: "0"
@@ -150,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
150
151
  requirements: []
151
152
 
152
153
  rubyforge_project:
153
- rubygems_version: 1.5.2
154
+ rubygems_version: 1.5.3
154
155
  signing_key:
155
156
  specification_version: 3
156
157
  summary: Queued JSON-RPC client and server. Works as normal RPC server, but through queue interface, so allows highly scalable, distributed and asynchronous remote API implementation and fast data processing. It's based on eventmachine and beanstalkd, so it's fast and thread safe.