qrpc 0.4.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +9 -6
- data/Gemfile +10 -4
- data/Gemfile.lock +34 -12
- data/LICENSE.txt +1 -1
- data/README.md +92 -25
- data/Rakefile +2 -1
- data/TODO.md +1 -3
- data/VERSION +1 -1
- data/lib/qrpc/client.rb +13 -5
- data/lib/qrpc/client/dispatcher.rb +66 -50
- data/lib/qrpc/client/exception.rb +8 -37
- data/lib/qrpc/client/job.rb +49 -16
- data/lib/qrpc/general.rb +61 -1
- data/lib/qrpc/generator/object-id.rb +43 -0
- data/lib/qrpc/generator/uuid.rb +43 -0
- data/lib/qrpc/locator.rb +11 -85
- data/lib/qrpc/locator/em-jack.rb +160 -0
- data/lib/qrpc/locator/evented-queue.rb +101 -0
- data/lib/qrpc/protocol/abstract.rb +119 -0
- data/lib/qrpc/protocol/abstract/error.rb +54 -0
- data/lib/qrpc/protocol/abstract/object.rb +81 -0
- data/lib/qrpc/protocol/abstract/request.rb +126 -0
- data/lib/qrpc/protocol/abstract/response.rb +103 -0
- data/lib/qrpc/protocol/json-rpc.rb +32 -0
- data/lib/qrpc/protocol/json-rpc/error.rb +71 -0
- data/lib/qrpc/protocol/json-rpc/native/exception-data.rb +247 -0
- data/lib/qrpc/protocol/json-rpc/native/qrpc-object.rb +137 -0
- data/lib/qrpc/protocol/json-rpc/request.rb +140 -0
- data/lib/qrpc/protocol/json-rpc/response.rb +146 -0
- data/lib/qrpc/protocol/object.rb +32 -0
- data/lib/qrpc/protocol/object/error.rb +46 -0
- data/lib/qrpc/protocol/object/request.rb +111 -0
- data/lib/qrpc/protocol/object/response.rb +93 -0
- data/lib/qrpc/server.rb +63 -48
- data/lib/qrpc/server/dispatcher.rb +5 -107
- data/lib/qrpc/server/job.rb +69 -19
- data/qrpc.gemspec +55 -19
- data/test-both.rb +85 -0
- data/test-client.rb +36 -8
- data/test-server.rb +17 -12
- metadata +181 -31
- data/lib/qrpc/protocol/exception-data.rb +0 -227
- data/lib/qrpc/protocol/qrpc-object.rb +0 -103
- data/lib/qrpc/protocol/request.rb +0 -46
@@ -0,0 +1,160 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
|
3
|
+
|
4
|
+
require "hash-utils/array"
|
5
|
+
require "unified-queues"
|
6
|
+
require "em-jack"
|
7
|
+
|
8
|
+
##
|
9
|
+
# General QRPC module.
|
10
|
+
#
|
11
|
+
|
12
|
+
module QRPC
|
13
|
+
|
14
|
+
##
|
15
|
+
# Resource locators.
|
16
|
+
#
|
17
|
+
|
18
|
+
module Locator
|
19
|
+
|
20
|
+
##
|
21
|
+
# Locator for 'em-jack' (so EventMachine Beanstalk implementation)
|
22
|
+
# queue type.
|
23
|
+
#
|
24
|
+
# @see https://github.com/dj2/em-jack
|
25
|
+
# @since 0.9.0
|
26
|
+
#
|
27
|
+
|
28
|
+
class EMJackLocator
|
29
|
+
|
30
|
+
##
|
31
|
+
# Holds the input queue interface.
|
32
|
+
# @return [UnifiedQueues::Multi] input queue
|
33
|
+
#
|
34
|
+
|
35
|
+
@input_queue
|
36
|
+
|
37
|
+
##
|
38
|
+
# Holds the input queue interface.
|
39
|
+
# @return [UnifiedQueues::Multi] output queue
|
40
|
+
#
|
41
|
+
|
42
|
+
@output_queue
|
43
|
+
|
44
|
+
##
|
45
|
+
# Contains queue name.
|
46
|
+
# @return [String]
|
47
|
+
#
|
48
|
+
|
49
|
+
attr_accessor :queue_name
|
50
|
+
@queue_name
|
51
|
+
|
52
|
+
##
|
53
|
+
# Contains host.
|
54
|
+
# @return [String]
|
55
|
+
#
|
56
|
+
|
57
|
+
attr_accessor :host
|
58
|
+
@host
|
59
|
+
|
60
|
+
##
|
61
|
+
# Contains port.
|
62
|
+
# @return [Integer]
|
63
|
+
#
|
64
|
+
|
65
|
+
attr_accessor :port
|
66
|
+
@port
|
67
|
+
|
68
|
+
##
|
69
|
+
# Parser.
|
70
|
+
#
|
71
|
+
|
72
|
+
PARSER = /^(.+)@(.+)(?:\:(\d+))?$/
|
73
|
+
|
74
|
+
##
|
75
|
+
# Default port.
|
76
|
+
#
|
77
|
+
|
78
|
+
DEFAULT_PORT = 11300
|
79
|
+
|
80
|
+
##
|
81
|
+
# Constructor.
|
82
|
+
#
|
83
|
+
# @param [String, Symbol] queue_name queue name
|
84
|
+
# @param [String] host host name
|
85
|
+
# @param [Integer] port port of the host
|
86
|
+
#
|
87
|
+
|
88
|
+
def initialize(queue_name, host = "localhost", port = 11300)
|
89
|
+
@queue_name = queue_name.to_s
|
90
|
+
@host = host
|
91
|
+
@port = port
|
92
|
+
end
|
93
|
+
|
94
|
+
##
|
95
|
+
# Parses the locator.
|
96
|
+
# Excpects form +<queue>@<host>:<port>+. Port is optional.
|
97
|
+
#
|
98
|
+
# @param [String] string locator in string form
|
99
|
+
# @return [QRPC::Locator] new instance
|
100
|
+
#
|
101
|
+
|
102
|
+
def self.parse(string)
|
103
|
+
match = string.match(self::PARSER)
|
104
|
+
|
105
|
+
queue = match.first
|
106
|
+
host = match.second
|
107
|
+
|
108
|
+
if match.length == 3
|
109
|
+
port = match.third
|
110
|
+
else
|
111
|
+
port = self::DEFAULT_PORT
|
112
|
+
end
|
113
|
+
|
114
|
+
port = port.to_i
|
115
|
+
|
116
|
+
##
|
117
|
+
|
118
|
+
return self::new(queue, host, port);
|
119
|
+
end
|
120
|
+
|
121
|
+
##
|
122
|
+
# Converts back to string.
|
123
|
+
# @return [String] locator in string form
|
124
|
+
#
|
125
|
+
|
126
|
+
def to_s
|
127
|
+
@queue_name + "@" + @host + ":" + @port.to_s
|
128
|
+
end
|
129
|
+
|
130
|
+
##
|
131
|
+
# Returns universal queue interface for input queue.
|
132
|
+
# @return [UnifiedQueues::Multi] queue
|
133
|
+
#
|
134
|
+
|
135
|
+
def input_queue
|
136
|
+
if @input_queue.nil?
|
137
|
+
@input_queue = UnifiedQueues::Multi::new EMJack::Connection, :host => @host, :port => @port
|
138
|
+
else
|
139
|
+
@input_queue
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
##
|
144
|
+
# Returns universal queue interface for output queue.
|
145
|
+
# @return [UnifiedQueues::Multi] queue
|
146
|
+
#
|
147
|
+
|
148
|
+
def output_queue
|
149
|
+
if @output_queue.nil?
|
150
|
+
@output_queue = UnifiedQueues::Multi::new EMJack::Connection, :host => @host, :port => @port
|
151
|
+
else
|
152
|
+
@output_queue
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
|
3
|
+
|
4
|
+
require "priority_queue/c_priority_queue"
|
5
|
+
require "hash-utils/array"
|
6
|
+
require "unified-queues"
|
7
|
+
require "evented-queue"
|
8
|
+
require "em-wrapper"
|
9
|
+
|
10
|
+
##
|
11
|
+
# General QRPC module.
|
12
|
+
#
|
13
|
+
|
14
|
+
module QRPC
|
15
|
+
|
16
|
+
##
|
17
|
+
# Resource locators.
|
18
|
+
#
|
19
|
+
|
20
|
+
module Locator
|
21
|
+
|
22
|
+
##
|
23
|
+
# Locator for 'evented-queue' queue type.
|
24
|
+
#
|
25
|
+
# @see https://github.com/martinkozak/evented-queue
|
26
|
+
# @since 0.9.0
|
27
|
+
#
|
28
|
+
|
29
|
+
class EventedQueueLocator
|
30
|
+
|
31
|
+
##
|
32
|
+
# Contains queue name.
|
33
|
+
# @return [String]
|
34
|
+
#
|
35
|
+
|
36
|
+
attr_accessor :queue_name
|
37
|
+
@queue_name
|
38
|
+
|
39
|
+
##
|
40
|
+
# Contains queue instance.
|
41
|
+
# @return [EventedQueue::Recurring]
|
42
|
+
#
|
43
|
+
|
44
|
+
attr_accessor :queue
|
45
|
+
@queue
|
46
|
+
|
47
|
+
##
|
48
|
+
# Constructor.
|
49
|
+
# @param [EventedQueue::Recurring] queue recurring evented queue instance
|
50
|
+
#
|
51
|
+
|
52
|
+
def initialize(queue_name, queue = self.default_queue)
|
53
|
+
@queue = queue
|
54
|
+
@queue_name = queue_name
|
55
|
+
end
|
56
|
+
|
57
|
+
##
|
58
|
+
# Returns the default evented queue type.
|
59
|
+
#
|
60
|
+
|
61
|
+
def default_queue
|
62
|
+
UnifiedQueues::Multi::new UnifiedQueues::Single, ::EM::Wrapper::new(REUQ), UnifiedQueues::Single, CPriorityQueue
|
63
|
+
end
|
64
|
+
|
65
|
+
alias :input_queue :queue
|
66
|
+
alias :output_queue :queue
|
67
|
+
|
68
|
+
|
69
|
+
##
|
70
|
+
# Helper recurring evented queue with unified queues support.
|
71
|
+
# @since 0.9.0
|
72
|
+
#
|
73
|
+
|
74
|
+
class REUQ < ::EventedQueue::Recurring
|
75
|
+
|
76
|
+
##
|
77
|
+
# Constructor.
|
78
|
+
#
|
79
|
+
|
80
|
+
def initialize(*args)
|
81
|
+
cls = args.first
|
82
|
+
args.shift
|
83
|
+
object = cls::new(*args)
|
84
|
+
super(object)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
=begin
|
92
|
+
q = QRPC::Locator::EventedQueue::new
|
93
|
+
q.input_queue.use(:xyz)
|
94
|
+
q.queue.push(:x, 2)
|
95
|
+
q.queue.push(:y, 3)
|
96
|
+
q.queue.subscribe(:xyz)
|
97
|
+
q.queue.pop do |i|
|
98
|
+
p i
|
99
|
+
end
|
100
|
+
q.queue.push(:z, 1)
|
101
|
+
=end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
|
3
|
+
|
4
|
+
require "hash-utils/object"
|
5
|
+
require "hash-utils/module"
|
6
|
+
require "qrpc/general"
|
7
|
+
require "hashie/mash"
|
8
|
+
require "abstract"
|
9
|
+
|
10
|
+
##
|
11
|
+
# General QRPC module.
|
12
|
+
#
|
13
|
+
|
14
|
+
module QRPC
|
15
|
+
|
16
|
+
##
|
17
|
+
# Protocols helper module.
|
18
|
+
# @since 0.9.0
|
19
|
+
#
|
20
|
+
|
21
|
+
module Protocol
|
22
|
+
|
23
|
+
##
|
24
|
+
# Abstract protocol implementation.
|
25
|
+
#
|
26
|
+
# @since 0.9.0
|
27
|
+
# @abstract
|
28
|
+
#
|
29
|
+
|
30
|
+
class Abstract
|
31
|
+
|
32
|
+
##
|
33
|
+
# Holds general object options.
|
34
|
+
# @return [Hashie::Mash] general options
|
35
|
+
#
|
36
|
+
|
37
|
+
attr_accessor :options
|
38
|
+
@options
|
39
|
+
|
40
|
+
##
|
41
|
+
# Holds classes to modules assignment cache.
|
42
|
+
#
|
43
|
+
|
44
|
+
@module_cache
|
45
|
+
|
46
|
+
##
|
47
|
+
# Constructor.
|
48
|
+
#
|
49
|
+
# @param [Hash] options general options for submodules
|
50
|
+
# @abstract
|
51
|
+
#
|
52
|
+
|
53
|
+
def initialize(options = { })
|
54
|
+
@options = Hashie::Mash::new(options)
|
55
|
+
@module_cache = { }
|
56
|
+
|
57
|
+
if self.instance_of? Abstract
|
58
|
+
not_implemented
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
# Returns new request object.
|
64
|
+
# @return [Class] class of the request object
|
65
|
+
#
|
66
|
+
|
67
|
+
def request
|
68
|
+
__module(:Request)
|
69
|
+
end
|
70
|
+
|
71
|
+
##
|
72
|
+
# Returns new response object.
|
73
|
+
# @return [Class] class of the response object
|
74
|
+
#
|
75
|
+
|
76
|
+
def response
|
77
|
+
__module(:Response)
|
78
|
+
end
|
79
|
+
|
80
|
+
##
|
81
|
+
# Returns new error object.
|
82
|
+
# @return [Class] class of the error object
|
83
|
+
#
|
84
|
+
|
85
|
+
def error
|
86
|
+
__module(:Error)
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
##
|
93
|
+
# Returns class from module according to specific driver
|
94
|
+
def __module(name)
|
95
|
+
mod = Module.get_module(self.class.name + "::" + name.to_s)
|
96
|
+
|
97
|
+
if not mod.in? @module_cache
|
98
|
+
cls = Class::new(mod)
|
99
|
+
opt = @options
|
100
|
+
|
101
|
+
cls.class_eval do
|
102
|
+
define_method :initialize do |options = { }, &block|
|
103
|
+
super(opt.merge(options), &block)
|
104
|
+
end
|
105
|
+
|
106
|
+
define_singleton_method :options do
|
107
|
+
opt
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
@module_cache[mod] = cls
|
112
|
+
end
|
113
|
+
|
114
|
+
@module_cache[mod]
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
|
3
|
+
|
4
|
+
require "abstract"
|
5
|
+
require "qrpc/general"
|
6
|
+
require "qrpc/protocol/abstract/object"
|
7
|
+
|
8
|
+
##
|
9
|
+
# General QRPC module.
|
10
|
+
#
|
11
|
+
|
12
|
+
module QRPC
|
13
|
+
|
14
|
+
##
|
15
|
+
# Protocols helper module.
|
16
|
+
# @since 0.9.0
|
17
|
+
#-
|
18
|
+
|
19
|
+
module Protocol
|
20
|
+
|
21
|
+
##
|
22
|
+
# Abstract protocol implementation.
|
23
|
+
# @since 0.9.0
|
24
|
+
#
|
25
|
+
|
26
|
+
class Abstract
|
27
|
+
|
28
|
+
##
|
29
|
+
# Abstract error object implementation.
|
30
|
+
#
|
31
|
+
# @since 0.9.0
|
32
|
+
# @abstract
|
33
|
+
#
|
34
|
+
|
35
|
+
class Error < Object
|
36
|
+
|
37
|
+
##
|
38
|
+
# Constructor.
|
39
|
+
#
|
40
|
+
# @param [Hash] init initial options
|
41
|
+
# @abstract
|
42
|
+
#
|
43
|
+
|
44
|
+
def initialize(init = { })
|
45
|
+
super(init)
|
46
|
+
if self.instance_of? Error
|
47
|
+
not_implemented
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
|
3
|
+
|
4
|
+
require "abstract"
|
5
|
+
require "hashie/mash"
|
6
|
+
require "qrpc/general"
|
7
|
+
require "qrpc/protocol/abstract"
|
8
|
+
|
9
|
+
##
|
10
|
+
# General QRPC module.
|
11
|
+
#
|
12
|
+
|
13
|
+
module QRPC
|
14
|
+
|
15
|
+
##
|
16
|
+
# Protocols helper module.
|
17
|
+
# @since 0.9.0
|
18
|
+
#
|
19
|
+
|
20
|
+
module Protocol
|
21
|
+
|
22
|
+
##
|
23
|
+
# Abstract protocol implementation.
|
24
|
+
# @since 0.9.0
|
25
|
+
#
|
26
|
+
|
27
|
+
class Abstract
|
28
|
+
|
29
|
+
##
|
30
|
+
# Abstract request implementation.
|
31
|
+
# @sice 0.9.0
|
32
|
+
#
|
33
|
+
|
34
|
+
class Object
|
35
|
+
|
36
|
+
##
|
37
|
+
# Holds the object options.
|
38
|
+
# @return [Hashie::Mash] options hash
|
39
|
+
#
|
40
|
+
|
41
|
+
attr_accessor :options
|
42
|
+
@options
|
43
|
+
|
44
|
+
##
|
45
|
+
# Constructor.
|
46
|
+
#
|
47
|
+
# @param [Hash] init initial options
|
48
|
+
# @abstract
|
49
|
+
#
|
50
|
+
|
51
|
+
def initialize(init = { })
|
52
|
+
@options = Hashie::Mash::new(init)
|
53
|
+
if self.instance_of? Object
|
54
|
+
not_implemented
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
##
|
59
|
+
# Assigns options to the object.
|
60
|
+
# @param [Hash] options hash with options
|
61
|
+
#
|
62
|
+
|
63
|
+
def assign_options(options = { })
|
64
|
+
@options = @options.merge(options)
|
65
|
+
end
|
66
|
+
|
67
|
+
##
|
68
|
+
# Serializes object to the resultant form.
|
69
|
+
#
|
70
|
+
# @return [String] serialized form
|
71
|
+
# @abstract
|
72
|
+
#
|
73
|
+
|
74
|
+
def serialize
|
75
|
+
not_implemented
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|