qrpc 0.4.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/CHANGES.txt +9 -6
  2. data/Gemfile +10 -4
  3. data/Gemfile.lock +34 -12
  4. data/LICENSE.txt +1 -1
  5. data/README.md +92 -25
  6. data/Rakefile +2 -1
  7. data/TODO.md +1 -3
  8. data/VERSION +1 -1
  9. data/lib/qrpc/client.rb +13 -5
  10. data/lib/qrpc/client/dispatcher.rb +66 -50
  11. data/lib/qrpc/client/exception.rb +8 -37
  12. data/lib/qrpc/client/job.rb +49 -16
  13. data/lib/qrpc/general.rb +61 -1
  14. data/lib/qrpc/generator/object-id.rb +43 -0
  15. data/lib/qrpc/generator/uuid.rb +43 -0
  16. data/lib/qrpc/locator.rb +11 -85
  17. data/lib/qrpc/locator/em-jack.rb +160 -0
  18. data/lib/qrpc/locator/evented-queue.rb +101 -0
  19. data/lib/qrpc/protocol/abstract.rb +119 -0
  20. data/lib/qrpc/protocol/abstract/error.rb +54 -0
  21. data/lib/qrpc/protocol/abstract/object.rb +81 -0
  22. data/lib/qrpc/protocol/abstract/request.rb +126 -0
  23. data/lib/qrpc/protocol/abstract/response.rb +103 -0
  24. data/lib/qrpc/protocol/json-rpc.rb +32 -0
  25. data/lib/qrpc/protocol/json-rpc/error.rb +71 -0
  26. data/lib/qrpc/protocol/json-rpc/native/exception-data.rb +247 -0
  27. data/lib/qrpc/protocol/json-rpc/native/qrpc-object.rb +137 -0
  28. data/lib/qrpc/protocol/json-rpc/request.rb +140 -0
  29. data/lib/qrpc/protocol/json-rpc/response.rb +146 -0
  30. data/lib/qrpc/protocol/object.rb +32 -0
  31. data/lib/qrpc/protocol/object/error.rb +46 -0
  32. data/lib/qrpc/protocol/object/request.rb +111 -0
  33. data/lib/qrpc/protocol/object/response.rb +93 -0
  34. data/lib/qrpc/server.rb +63 -48
  35. data/lib/qrpc/server/dispatcher.rb +5 -107
  36. data/lib/qrpc/server/job.rb +69 -19
  37. data/qrpc.gemspec +55 -19
  38. data/test-both.rb +85 -0
  39. data/test-client.rb +36 -8
  40. data/test-server.rb +17 -12
  41. metadata +181 -31
  42. data/lib/qrpc/protocol/exception-data.rb +0 -227
  43. data/lib/qrpc/protocol/qrpc-object.rb +0 -103
  44. data/lib/qrpc/protocol/request.rb +0 -46
@@ -47,16 +47,34 @@ module QRPC
47
47
 
48
48
  @api
49
49
 
50
+ ##
51
+ # Indicates API methods synchronicity.
52
+ # @since 0.4.0
53
+ #
54
+
55
+ @synchronicity
56
+
57
+ ##
58
+ # Holds protocol handling instance.
59
+ # @since 0.9.0
60
+ #
61
+
62
+ @protocol
63
+
50
64
  ##
51
65
  # Constructor.
52
66
  #
53
67
  # @param [Object] object which will serve as API
68
+ # @param [Symbol] synchronicity API methods synchronicity
54
69
  # @param [EM::Beanstalk::Job] job beanstalk job
70
+ # @param [QRPC::Protocol::Abstract] protocol protocol handling instance
55
71
  #
56
72
 
57
- def initialize(api, job)
58
- @api = api
73
+ def initialize(api, synchronicity, job, protocol = QRPC::default_protocol)
74
+ @synchronicity = synchronicity
75
+ @protocol = protocol
59
76
  @job = job
77
+ @api = api
60
78
  end
61
79
 
62
80
  ##
@@ -68,19 +86,47 @@ module QRPC
68
86
  error = nil
69
87
  request = self.request
70
88
 
71
- begin
72
- @api.precall if @api.respond_to? :precall
73
- result = @api.send(request.method, *request.params)
74
- @api.postcall if @api.respond_to? :postcall
75
- rescue ::Exception => e
76
- error = self.generate_error(request, e)
89
+ if not request.notification?
90
+ finalize = Proc::new do
91
+ options = {
92
+ :result => result,
93
+ :error => error,
94
+ :request => request
95
+ }
96
+
97
+ response = @protocol.response::new(options)
98
+ self.set_deferred_status(:succeeded, response.serialize)
99
+ end
77
100
  end
78
101
 
79
- response = request.class::version.response::create(result, error, :id => request.id)
80
- response.qrpc = QRPC::Protocol::QrpcObject::create
81
102
 
82
- @job.delete()
83
- self.set_deferred_status(:succeeded, response.to_json)
103
+ if @synchronicity == :synchronous
104
+ begin
105
+ result = @api.send(request.method, *request.params)
106
+ rescue ::Exception => e
107
+ if not request.notification?
108
+ error = self.generate_error(request, e)
109
+ end
110
+ end
111
+
112
+ if not request.notification?
113
+ finalize.call()
114
+ end
115
+ else
116
+ begin
117
+ @api.send(request.method, *request.params) do |res|
118
+ if not request.notification?
119
+ result = res
120
+ finalize.call()
121
+ end
122
+ end
123
+ rescue ::Exception => e
124
+ if not request.notification?
125
+ error = self.generate_error(request, e)
126
+ finalize.call()
127
+ end
128
+ end
129
+ end
84
130
  end
85
131
 
86
132
  ##
@@ -90,10 +136,10 @@ module QRPC
90
136
 
91
137
  def request
92
138
  if @request.nil?
93
- @request = JsonRpcObjects::Request::parse(@job.body)
139
+ @request = @protocol.request::parse(@job)
140
+ else
141
+ @request
94
142
  end
95
-
96
- return @request
97
143
  end
98
144
 
99
145
  ##
@@ -106,7 +152,7 @@ module QRPC
106
152
  #
107
153
 
108
154
  def priority
109
- priority = self.request.qrpc["priority"]
155
+ priority = self.request.priority
110
156
  if priority.nil?
111
157
  priority = QRPC::DEFAULT_PRIORITY
112
158
  else
@@ -122,7 +168,7 @@ module QRPC
122
168
  #
123
169
 
124
170
  def client
125
- self.request.qrpc["client"]
171
+ self.request.client
126
172
  end
127
173
 
128
174
 
@@ -133,8 +179,12 @@ module QRPC
133
179
  #
134
180
 
135
181
  def generate_error(request, exception)
136
- data = QRPC::Protocol::ExceptionData::create(exception)
137
- request.class::version.error::create(100, "exception raised during processing the request", :error => data)
182
+ options = {
183
+ :exception => exception,
184
+ :request => request
185
+ }
186
+
187
+ @protocol.error::new(options)
138
188
  end
139
189
 
140
190
  end
data/qrpc.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "qrpc"
8
- s.version = "0.4.0"
8
+ s.version = "0.9.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\u{e1}k"]
12
- s.date = "2012-02-19"
12
+ s.date = "2012-05-24"
13
13
  s.email = "martinkozak@martinkozak.net"
14
14
  s.extra_rdoc_files = [
15
15
  "LICENSE.txt",
@@ -30,49 +30,85 @@ Gem::Specification.new do |s|
30
30
  "lib/qrpc/client/exception.rb",
31
31
  "lib/qrpc/client/job.rb",
32
32
  "lib/qrpc/general.rb",
33
+ "lib/qrpc/generator/object-id.rb",
34
+ "lib/qrpc/generator/uuid.rb",
33
35
  "lib/qrpc/locator.rb",
34
- "lib/qrpc/protocol/exception-data.rb",
35
- "lib/qrpc/protocol/qrpc-object.rb",
36
- "lib/qrpc/protocol/request.rb",
36
+ "lib/qrpc/locator/em-jack.rb",
37
+ "lib/qrpc/locator/evented-queue.rb",
38
+ "lib/qrpc/protocol/abstract.rb",
39
+ "lib/qrpc/protocol/abstract/error.rb",
40
+ "lib/qrpc/protocol/abstract/object.rb",
41
+ "lib/qrpc/protocol/abstract/request.rb",
42
+ "lib/qrpc/protocol/abstract/response.rb",
43
+ "lib/qrpc/protocol/json-rpc.rb",
44
+ "lib/qrpc/protocol/json-rpc/error.rb",
45
+ "lib/qrpc/protocol/json-rpc/native/exception-data.rb",
46
+ "lib/qrpc/protocol/json-rpc/native/qrpc-object.rb",
47
+ "lib/qrpc/protocol/json-rpc/request.rb",
48
+ "lib/qrpc/protocol/json-rpc/response.rb",
49
+ "lib/qrpc/protocol/object.rb",
50
+ "lib/qrpc/protocol/object/error.rb",
51
+ "lib/qrpc/protocol/object/request.rb",
52
+ "lib/qrpc/protocol/object/response.rb",
37
53
  "lib/qrpc/server.rb",
38
54
  "lib/qrpc/server/dispatcher.rb",
39
55
  "lib/qrpc/server/job.rb",
40
56
  "qrpc.gemspec",
57
+ "test-both.rb",
41
58
  "test-client.rb",
42
59
  "test-server.rb"
43
60
  ]
44
61
  s.homepage = "http://github.com/martinkozak/qrpc"
45
62
  s.licenses = ["MIT"]
63
+ s.post_install_message = "\nQRPC: API of the 0.9.x version (and 1.0 in future) is partialy incompatible with the older versions. Modifications of your current applications may be necessary for upgrading them to the latest version. \n\n"
46
64
  s.require_paths = ["lib"]
47
- s.rubygems_version = "1.8.17"
48
- s.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."
65
+ s.rubygems_version = "1.8.24"
66
+ s.summary = "Queued 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 typically on Beanstalk, so it's fast and thread safe."
49
67
 
50
68
  if s.respond_to? :specification_version then
51
69
  s.specification_version = 3
52
70
 
53
71
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
54
- s.add_runtime_dependency(%q<json-rpc-objects>, [">= 0.3.3"])
55
- s.add_runtime_dependency(%q<depq>, [">= 0.4"])
56
- s.add_runtime_dependency(%q<em-jack>, [">= 0.1.3"])
72
+ s.add_runtime_dependency(%q<json-rpc-objects>, [">= 0.4.1"])
73
+ s.add_runtime_dependency(%q<PriorityQueue>, [">= 0.1.2"])
74
+ s.add_runtime_dependency(%q<unified-queues>, [">= 0"])
75
+ s.add_runtime_dependency(%q<evented-queue>, [">= 0"])
57
76
  s.add_runtime_dependency(%q<eventmachine>, [">= 0"])
58
- s.add_runtime_dependency(%q<uuid>, [">= 2.3.2"])
77
+ s.add_runtime_dependency(%q<hash-utils>, [">= 1.1.0"])
78
+ s.add_runtime_dependency(%q<em-wrapper>, [">= 0"])
79
+ s.add_runtime_dependency(%q<abstract>, [">= 0"])
80
+ s.add_runtime_dependency(%q<em-jack>, [">= 0.1.3"])
81
+ s.add_runtime_dependency(%q<hashie>, [">= 1.0.0"])
82
+ s.add_runtime_dependency(%q<uuid>, [">= 2.0.0"])
59
83
  s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
60
84
  s.add_development_dependency(%q<jeweler2>, [">= 2.0.0"])
61
85
  else
62
- s.add_dependency(%q<json-rpc-objects>, [">= 0.3.3"])
63
- s.add_dependency(%q<depq>, [">= 0.4"])
64
- s.add_dependency(%q<em-jack>, [">= 0.1.3"])
86
+ s.add_dependency(%q<json-rpc-objects>, [">= 0.4.1"])
87
+ s.add_dependency(%q<PriorityQueue>, [">= 0.1.2"])
88
+ s.add_dependency(%q<unified-queues>, [">= 0"])
89
+ s.add_dependency(%q<evented-queue>, [">= 0"])
65
90
  s.add_dependency(%q<eventmachine>, [">= 0"])
66
- s.add_dependency(%q<uuid>, [">= 2.3.2"])
91
+ s.add_dependency(%q<hash-utils>, [">= 1.1.0"])
92
+ s.add_dependency(%q<em-wrapper>, [">= 0"])
93
+ s.add_dependency(%q<abstract>, [">= 0"])
94
+ s.add_dependency(%q<em-jack>, [">= 0.1.3"])
95
+ s.add_dependency(%q<hashie>, [">= 1.0.0"])
96
+ s.add_dependency(%q<uuid>, [">= 2.0.0"])
67
97
  s.add_dependency(%q<bundler>, [">= 1.0.0"])
68
98
  s.add_dependency(%q<jeweler2>, [">= 2.0.0"])
69
99
  end
70
100
  else
71
- s.add_dependency(%q<json-rpc-objects>, [">= 0.3.3"])
72
- s.add_dependency(%q<depq>, [">= 0.4"])
73
- s.add_dependency(%q<em-jack>, [">= 0.1.3"])
101
+ s.add_dependency(%q<json-rpc-objects>, [">= 0.4.1"])
102
+ s.add_dependency(%q<PriorityQueue>, [">= 0.1.2"])
103
+ s.add_dependency(%q<unified-queues>, [">= 0"])
104
+ s.add_dependency(%q<evented-queue>, [">= 0"])
74
105
  s.add_dependency(%q<eventmachine>, [">= 0"])
75
- s.add_dependency(%q<uuid>, [">= 2.3.2"])
106
+ s.add_dependency(%q<hash-utils>, [">= 1.1.0"])
107
+ s.add_dependency(%q<em-wrapper>, [">= 0"])
108
+ s.add_dependency(%q<abstract>, [">= 0"])
109
+ s.add_dependency(%q<em-jack>, [">= 0.1.3"])
110
+ s.add_dependency(%q<hashie>, [">= 1.0.0"])
111
+ s.add_dependency(%q<uuid>, [">= 2.0.0"])
76
112
  s.add_dependency(%q<bundler>, [">= 1.0.0"])
77
113
  s.add_dependency(%q<jeweler2>, [">= 2.0.0"])
78
114
  end
data/test-both.rb ADDED
@@ -0,0 +1,85 @@
1
+ # encoding: utf-8
2
+
3
+ $:.unshift("./lib")
4
+ $:.push("./lib")
5
+
6
+ require "rubygems"
7
+ require "qrpc/server"
8
+ require "qrpc/client"
9
+ require "qrpc/locator/evented-queue"
10
+ require "qrpc/locator/em-jack"
11
+ require "eventmachine"
12
+
13
+ #require "qrpc/generator/uuid"
14
+ require "qrpc/generator/object-id"
15
+ require "qrpc/protocol/object"
16
+
17
+ #require "json-rpc-objects/serializer/bson"
18
+ require "json-rpc-objects/serializer/json"
19
+ #require "json-rpc-objects/serializer/yaml"
20
+ #require "json-rpc-objects/serializer/psych"
21
+ #require "json-rpc-objects/serializer/marshal"
22
+ require "json-rpc-objects/serializer/msgpack"
23
+
24
+ EM::run do
25
+ generator = QRPC::Generator::ObjectID::new
26
+ queue = QRPC::Locator::EventedQueueLocator::new("test")
27
+ #queue1 = QRPC::Locator::EMJackLocator::new("test")
28
+ #queue2 = QRPC::Locator::EMJackLocator::new("test")
29
+ protocol = QRPC::Protocol::Object::new
30
+
31
+ ###############
32
+ # Server
33
+ ###############
34
+
35
+ class Foo
36
+ def subtract(x, y)
37
+ puts "response"
38
+ x - y
39
+ end
40
+ end
41
+
42
+ server = QRPC::Server::new(Foo::new, :synchronous, protocol)
43
+ server.listen! queue
44
+
45
+ ###############
46
+ # Client
47
+ ###############
48
+
49
+ client = QRPC::Client::new(queue, generator, protocol)
50
+ # puts client.inspect
51
+
52
+ # client.something_bad do |i|
53
+ # puts i
54
+ # end
55
+
56
+ count = 0
57
+
58
+ make = Proc::new do
59
+ puts "request"
60
+
61
+ client.subtract(2, 3) do |i|
62
+ puts "x", i
63
+ count += 1
64
+ end
65
+
66
+ #count += 1
67
+ #p queue.queue
68
+
69
+ if count < 7
70
+ EM::next_tick do
71
+ make.call()
72
+ end
73
+ else
74
+ #EM::stop
75
+ end
76
+ end
77
+
78
+ make.call()
79
+
80
+ # client.subtract(2, 3) do |i|
81
+ # puts "x"
82
+ # puts i
83
+ # end
84
+
85
+ end
data/test-client.rb CHANGED
@@ -3,13 +3,28 @@
3
3
  require "rubygems"
4
4
 
5
5
  $:.push("./lib")
6
+ $:.unshift("./lib")
6
7
  require "qrpc/client"
7
- require "qrpc/locator"
8
+ require "qrpc/locator/em-jack"
8
9
  require "eventmachine"
9
10
 
11
+ #require "qrpc/generator/uuid"
12
+ require "qrpc/generator/object-id"
13
+
14
+ require "qrpc/protocol/json-rpc"
15
+ #require "json-rpc-objects/serializer/bson"
16
+ #require "json-rpc-objects/serializer/psych"
17
+ require "json-rpc-objects/serializer/json"
18
+ #require "json-rpc-objects/serializer/yaml"
19
+ #require "json-rpc-objects/serializer/marshal"
20
+ require "json-rpc-objects/serializer/msgpack"
10
21
 
11
22
  EM::run do
12
- client = QRPC::Client::new QRPC::Locator::new :test
23
+ generator = QRPC::Generator::ObjectID::new
24
+ locator = QRPC::Locator::EMJackLocator::new(:test)
25
+ serializer = JsonRpcObjects::Serializer::JSON::new
26
+ protocol = QRPC::Protocol::JsonRpc::new(:serializer => serializer)
27
+ client = QRPC::Client::new(locator, generator, protocol)
13
28
  # puts client.inspect
14
29
 
15
30
  # client.something_bad do |i|
@@ -18,16 +33,25 @@ EM::run do
18
33
 
19
34
  count = 0
20
35
 
21
- 10000.times do
36
+ make = Proc::new do
22
37
  client.subtract(2, 3) do |i|
23
38
  puts i
24
- count += 1
25
- if count >= 10000
26
- EM::stop
39
+ if i == 4
40
+ count += 1
41
+ end
42
+ end
43
+
44
+ if count < 10
45
+ EM::next_tick do
46
+ make.call()
27
47
  end
48
+ else
49
+ EM::stop
28
50
  end
29
51
  end
30
52
 
53
+ make.call()
54
+
31
55
  # client.subtract(3, 2) do |i|
32
56
  # puts i
33
57
  # end
@@ -41,10 +65,13 @@ b = Beanstalk::Pool::new(["localhost:11300"])
41
65
  req1 = JsonRpcObjects::Request::create(:subtract, [2, 3], :id => "job1", :qrpc => { :version => "1.0", :client => :cc })
42
66
  req2 = JsonRpcObjects::Request::create(:something_bad, nil, :id => "job2", :qrpc => { :version => "1.0", :client => :cc, :priority => 20 })
43
67
 
68
+ req1.serializer = JsonRpcObjects::Serializer::BSON::new
69
+ req2.serializer = JsonRpcObjects::Serializer::BSON::new
70
+
44
71
  b.use("qrpc-test-input")
45
72
  b.watch("qrpc-cc-output")
46
- b.put(req1.to_json)
47
- b.put(req2.to_json)
73
+ b.put(req1.serialize)
74
+ b.put(req2.serialize)
48
75
 
49
76
  job = b.reserve
50
77
  puts job.body
@@ -54,6 +81,7 @@ job = b.reserve
54
81
  puts job.body
55
82
  job.delete
56
83
  =end
84
+
57
85
  =begin
58
86
  100.times do
59
87
  b.put(req1.to_json)
data/test-server.rb CHANGED
@@ -1,24 +1,29 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require "rubygems"
4
+
4
5
  $:.push("./lib")
6
+ $:.unshift("./lib")
7
+
8
+ require "qrpc/protocol/json-rpc"
9
+ #require "json-rpc-objects/serializer/bson"
10
+ require "json-rpc-objects/serializer/json"
11
+ #require "json-rpc-objects/serializer/yaml"
12
+ #require "json-rpc-objects/serializer/psych"
13
+ #require "json-rpc-objects/serializer/marshal"
14
+ require "json-rpc-objects/serializer/msgpack"
5
15
 
6
16
  class Foo
7
- def precall
8
- puts "precall"
9
- end
10
-
11
17
  def subtract(x, y)
12
- puts "call"
13
- x - y
14
- end
15
-
16
- def postcall
17
- puts "postcall"
18
+ x - y + 5
18
19
  end
19
20
  end
20
21
 
21
22
 
22
23
  require "qrpc/server"
23
- server = QRPC::Server::new(Foo::new)
24
- server.listen! QRPC::Locator::new("test"), :max_jobs => 0
24
+ require "qrpc/locator/em-jack"
25
+
26
+ serializer = JsonRpcObjects::Serializer::JSON::new
27
+ protocol = QRPC::Protocol::JsonRpc::new(:serializer => serializer)
28
+ server = QRPC::Server::new(Foo::new, :synchronous, protocol)
29
+ server.listen! QRPC::Locator::EMJackLocator::new("test")