skein 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6896b1151e348573c5b58ee131b6f568373d7547
4
- data.tar.gz: 4ae4f3c7de9c5eaf0d17e9e0ec77ef02390824f1
3
+ metadata.gz: d56cf67111c3a47096df2c6936b9a66329648bc4
4
+ data.tar.gz: cc63a8071f98e2e1efb3e1281886c104e0709e20
5
5
  SHA512:
6
- metadata.gz: 32a30b3dc6c37ac747d372f9379f90463f0c36de086ef2eb464eedc0d5f93b8b88e8737c5d0cd3a42dcbed0ccdd0d12e43bf2ac6f4f7679527d7f2e8e8aa88cc
7
- data.tar.gz: fb8169c2061892dbe1c2c05da18a672646e09abf773a020ccbe556cabdbc997b6c8d85548f8392a751d834dc7a13c1970e59147d7d73d58d778caa3be50cafde
6
+ metadata.gz: ce7e54be719abd78fd9c87d0adfd69445820b019776df34062f284a284344be608ff414a322aa4c05ba9294c0507f28a33fce189ab03e2c6dfb420b22c5a9ab5
7
+ data.tar.gz: 0a3306cccb1edc161543003c6c41d3ef5686645b45bf507c112002f09cc6565a27dbfdca6531572dc1cc11f9994b821de730892db9f3bfaa575e3e46b783d322
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.3.1
data/bin/skein CHANGED
@@ -10,10 +10,10 @@ require_relative '../lib/skein'
10
10
  # == Support Classes ========================================================
11
11
 
12
12
  class EchoWorker < Skein::Client::Worker
13
- def initialize(queue_name, options = nil)
14
- super(queue_name, options || { })
13
+ def initialize(queue_name, debug: false, **options)
14
+ super(queue_name, options)
15
15
 
16
- @debug = options && options[:debug]
16
+ @debug = debug
17
17
  end
18
18
 
19
19
  def echo(text)
@@ -56,7 +56,9 @@ end
56
56
 
57
57
  options = {
58
58
  count: 1,
59
- threads: 1
59
+ threads: 1,
60
+ queue_name: 'test_echo',
61
+ exchange_name: nil
60
62
  }
61
63
 
62
64
  parser = OptionParser.new do |parser|
@@ -77,6 +79,13 @@ parser = OptionParser.new do |parser|
77
79
  options[:debug] = true
78
80
  end
79
81
 
82
+ parser.on('-e', '--exchange=s') do |s|
83
+ options[:exchange_name] = s
84
+ end
85
+ parser.on('-q', '--queue=s') do |s|
86
+ options[:queue_name] = s
87
+ end
88
+
80
89
  parser.on('-h', '--help') do
81
90
  puts parser
82
91
  exit(0)
@@ -135,20 +144,33 @@ when 'echo'
135
144
  end
136
145
  end
137
146
 
147
+ if (options[:threads] > 1)
148
+ # Warm up RabbitMQ driver, force all autoloads
149
+ Skein::Client.new.close
150
+ end
151
+
138
152
  options[:threads].times.map do
139
153
  in_thread(options) do
140
154
  client = Skein::Client.new
141
- rpc = client.rpc('test_echo')
155
+ rpc = client.rpc(options[:exchange_name], routing_key: options[:queue_name])
142
156
 
143
157
  options[:count].times do |i|
144
158
  test_data = SecureRandom.uuid
145
159
 
160
+ if (options[:verbose])
161
+ print '[%s] ??? (%d/%d)' % [
162
+ '---',
163
+ i + 1,
164
+ options[:count]
165
+ ]
166
+ end
167
+
146
168
  response = rpc.echo(test_data)
147
169
 
148
170
  results << (response == test_data)
149
171
 
150
172
  if (options[:verbose])
151
- puts '[%s] %s (%d/%d)' % [
173
+ puts "\r[%s] %s (%d/%d)" % [
152
174
  (response == test_data ? 'OK' : 'ERR'),
153
175
  response.inspect,
154
176
  i + 1,
@@ -177,7 +199,11 @@ when 'echo'
177
199
  when 'echo_server'
178
200
  rescue_safely(options) do
179
201
  options[:threads].times.map do
180
- EchoWorker.new('test_echo')
202
+ EchoWorker.new(
203
+ options[:queue_name],
204
+ exchange_name: options[:exchange_name],
205
+ debug: options[:debug]
206
+ )
181
207
  end.each(&:join)
182
208
  end
183
209
  else
data/lib/skein.rb CHANGED
@@ -14,6 +14,7 @@ end
14
14
 
15
15
  require_relative './skein/connected'
16
16
 
17
+ require_relative './skein/adapter'
17
18
  require_relative './skein/client'
18
19
  require_relative './skein/config'
19
20
  require_relative './skein/context'
@@ -0,0 +1,18 @@
1
+ module Skein::Adapter
2
+ # == Mixin Methods =========================================================
3
+
4
+ def subscribe(queue, block: true, manual_ack: true)
5
+ case (queue.class.to_s.split(/::/)[0])
6
+ when 'Bunny'
7
+ queue.subscribe(block: block, manual_ack: manual_ack) do |delivery_info, properties, payload|
8
+ yield(payload, delivery_info[:delivery_tag], properties[:reply_to])
9
+ end
10
+ when 'MarchHare'
11
+ queue.subscribe(block: block, manual_ack: manual_ack) do |metadata, payload|
12
+ yield(payload, metadata.delivery_tag, metadata.reply_to)
13
+ end
14
+ end
15
+ end
16
+
17
+ extend self
18
+ end
data/lib/skein/client.rb CHANGED
@@ -28,20 +28,37 @@ class Skein::Client < Skein::Connected
28
28
  super(connection: connection, context: context)
29
29
  end
30
30
 
31
- def rpc(queue_name = nil)
32
- Skein::Client::RPC.new(queue_name, connection: self.connection, context: self.context)
31
+ def rpc(exchange_name = nil, routing_key: nil)
32
+ Skein::Client::RPC.new(
33
+ exchange_name,
34
+ routing_key: routing_key,
35
+ connection: self.connection,
36
+ context: self.context
37
+ )
33
38
  end
34
39
 
35
40
  def receiver
36
- Skein::Client::Receiver.new(connection: self.connection, context: self.context)
41
+ Skein::Client::Receiver.new(
42
+ connection: self.connection,
43
+ context: self.context
44
+ )
37
45
  end
38
46
 
39
47
  def publisher(queue_name)
40
- Skein::Client::Publisher.new(queue_name, connection: self.connection, context: self.context)
48
+ Skein::Client::Publisher.new(
49
+ queue_name,
50
+ connection: self.connection,
51
+ context: self.context
52
+ )
41
53
  end
42
54
 
43
55
  def subscriber(queue_name, routing_key = nil)
44
- Skein::Client::Subscriber.new(queue_name, routing_key, connection: self.connection, context: self.context)
56
+ Skein::Client::Subscriber.new(
57
+ queue_name,
58
+ routing_key,
59
+ connection: self.connection,
60
+ context: self.context
61
+ )
45
62
  end
46
63
  end
47
64
 
@@ -4,33 +4,23 @@ require 'fiber'
4
4
  class Skein::Client::RPC < Skein::Connected
5
5
  # == Constants ============================================================
6
6
 
7
- QUEUE_NAME_DEFAULT = 'skein_rpc'.freeze
7
+ EXCHANGE_NAME_DEFAULT = ''.freeze
8
8
 
9
9
  # == Properties ===========================================================
10
10
 
11
11
  # == Instance Methods =====================================================
12
12
 
13
- def initialize(queue_name = nil, connection: nil, context: nil)
13
+ def initialize(exchange_name = nil, routing_key: nil, connection: nil, context: nil)
14
14
  super(connection: connection, context: context)
15
15
 
16
- @rpc_queue = self.channel.queue(queue_name || QUEUE_NAME_DEFAULT, durable: true)
16
+ @rpc_exchange = self.channel.direct(exchange_name || EXCHANGE_NAME_DEFAULT, durable: true)
17
+ @routing_key = routing_key
17
18
  @response_queue = self.channel.queue(@ident, durable: true, header: true, auto_delete: true)
18
19
 
19
20
  @callback = { }
20
21
 
21
- @consumer = @response_queue.subscribe do |metadata, payload, extra|
22
- # FIX: Deal with mixup between Bunny and MarchHare
23
- # puts [metadata,payload,extra].inspect
24
-
25
- # puts [metadata,payload,extra].map(&:class).inspect
26
-
27
- if (extra)
28
- payload = extra
29
- elsif (!payload)
30
- payload = metadata
31
- end
32
-
33
- begin
22
+ @consumer = Skein::Adapter.subscribe(@response_queue, block: false) do |payload, delivery_tag, reply_to|
23
+ self.context.trap do
34
24
  response = JSON.load(payload)
35
25
 
36
26
  if (callback = @callback.delete(response['id']))
@@ -41,9 +31,8 @@ class Skein::Client::RPC < Skein::Connected
41
31
  callback.call
42
32
  end
43
33
  end
44
- rescue => e
45
- # FIX: Error handling
46
- puts e.inspect
34
+
35
+ self.channel.acknowledge(delivery_tag)
47
36
  end
48
37
  end
49
38
  end
@@ -67,10 +56,11 @@ class Skein::Client::RPC < Skein::Connected
67
56
  id: message_id
68
57
  )
69
58
 
70
- @channel.default_exchange.publish(
59
+ @rpc_exchange.publish(
71
60
  request,
72
- routing_key: @rpc_queue.name,
61
+ routing_key: @routing_key,
73
62
  reply_to: blocking ? @ident : nil,
63
+ content_type: 'application/json',
74
64
  message_id: message_id
75
65
  )
76
66
 
@@ -1,13 +1,19 @@
1
1
  class Skein::Client::Subscriber < Skein::Connected
2
2
  # == Instance Methods =====================================================
3
3
 
4
- def initialize(queue_name, routing_key = nil, connection: nil, context: nil)
4
+ def initialize(exchange, routing_key = nil, connection: nil, context: nil)
5
5
  super(connection: connection, context: context)
6
6
 
7
- @queue = self.channel.topic(queue_name)
8
- @subscribe_queue = self.channel.queue('', exclusive: true)
7
+ @exchange =
8
+ case (exchange)
9
+ when String, Symbol
10
+ self.channel.topic(exchange)
11
+ else
12
+ exchange
13
+ end
9
14
 
10
- @subscribe_queue.bind(@queue, routing_key: routing_key)
15
+ @subscribe_queue = self.channel.queue('', exclusive: true)
16
+ @subscribe_queue.bind(@exchange, routing_key: routing_key)
11
17
  end
12
18
 
13
19
  def listen
@@ -3,25 +3,33 @@ require 'json'
3
3
  class Skein::Client::Worker < Skein::Connected
4
4
  # == Instance Methods =====================================================
5
5
 
6
- def initialize(queue_name, connection: nil, context: nil)
6
+ def initialize(queue_name, exchange_name: nil, connection: nil, context: nil)
7
7
  super(connection: connection, context: context)
8
8
 
9
9
  lock do
10
- queue = self.channel.queue(queue_name, durable: true)
10
+ @reply_exchange = self.channel.default_exchange
11
+ @queue = self.channel.queue(queue_name, durable: true)
11
12
 
12
- @handler = Skein::Handler.for(self)
13
+ if (exchange_name)
14
+ @exchange = self.channel.direct(exchange_name, durable: true)
15
+
16
+ @queue.bind(@exchange)
17
+ end
13
18
 
14
- @subscriber = Skein::Client::Subscriber.new(queue_name, connection: self.connection)
19
+ @handler = Skein::Handler.for(self)
15
20
 
16
21
  @thread = Thread.new do
17
- @subscriber.listen do |payload, delivery_tag, reply_to|
22
+ Thread.abort_on_exception = true
23
+
24
+ Skein::Adapter.subscribe(@queue) do |payload, delivery_tag, reply_to|
18
25
  @handler.handle(payload) do |reply_json|
19
26
  channel.acknowledge(delivery_tag, true)
20
27
 
21
28
  if (reply_to)
22
- channel.default_exchange.publish(
29
+ @reply_exchange.publish(
23
30
  reply_json,
24
- routing_key: reply_to
31
+ routing_key: reply_to,
32
+ content_type: 'application/json'
25
33
  )
26
34
  end
27
35
  end
@@ -46,6 +54,4 @@ class Skein::Client::Worker < Skein::Connected
46
54
  # callback-style delegation.
47
55
  false
48
56
  end
49
-
50
- protected
51
57
  end
data/lib/skein/context.rb CHANGED
@@ -35,4 +35,10 @@ class Skein::Context
35
35
  def exception!(*args)
36
36
  @reporter and @reporter.exception!(*args)
37
37
  end
38
+
39
+ def trap
40
+ yield
41
+ rescue => e
42
+ self.exception!(e)
43
+ end
38
44
  end
data/lib/skein/handler.rb CHANGED
@@ -1,4 +1,8 @@
1
1
  class Skein::Handler
2
+ # == Properties ===========================================================
3
+
4
+ attr_reader :context
5
+
2
6
  # == Class Methods ========================================================
3
7
 
4
8
  def self.for(target)
@@ -12,24 +16,23 @@ class Skein::Handler
12
16
 
13
17
  # == Instance Methods =====================================================
14
18
 
15
- def initialize(target)
19
+ def initialize(target, context = nil)
16
20
  @target = target
21
+ @context = context
17
22
  end
18
23
 
19
24
  def handle(message_json)
20
- # REFACTOR: Roll this into a module to keep it more contained.
21
- # REFACTOR: Use Skein::RPC::Request
22
25
  request =
23
26
  begin
24
27
  JSON.load(message_json)
25
28
 
26
29
  rescue Object => e
27
- @context.exception!(e, message_json)
30
+ @context and @context.exception!(e, message_json)
28
31
 
29
32
  return yield(JSON.dump(
30
33
  result: nil,
31
34
  error: '[%s] %s' % [ e.class, e ],
32
- id: request['id']
35
+ id: nil
33
36
  ))
34
37
  end
35
38
 
@@ -71,7 +74,7 @@ class Skein::Handler
71
74
  ))
72
75
  end
73
76
  rescue Object => e
74
- @reporter and @reporter.exception!(e, message_json)
77
+ @context and @context.exception!(e, message_json)
75
78
 
76
79
  yield(JSON.dump(
77
80
  result: nil,
data/skein.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: skein 0.3.0 ruby lib
5
+ # stub: skein 0.3.1 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "skein".freeze
9
- s.version = "0.3.0"
9
+ s.version = "0.3.1"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["Scott Tadman".freeze]
14
- s.date = "2016-12-07"
14
+ s.date = "2016-12-12"
15
15
  s.description = "Wrapper for RabbitMQ that makes blocking RPC calls and handles pub-sub broadcasts.".freeze
16
16
  s.email = "tadman@postageapp.com".freeze
17
17
  s.executables = ["skein".freeze]
@@ -29,6 +29,7 @@ Gem::Specification.new do |s|
29
29
  "config/.gitignore",
30
30
  "config/skein.yml.example",
31
31
  "lib/skein.rb",
32
+ "lib/skein/adapter.rb",
32
33
  "lib/skein/client.rb",
33
34
  "lib/skein/client/publisher.rb",
34
35
  "lib/skein/client/rpc.rb",
@@ -68,7 +69,7 @@ Gem::Specification.new do |s|
68
69
  ]
69
70
  s.homepage = "http://github.com/postageapp/skein".freeze
70
71
  s.licenses = ["closed".freeze]
71
- s.rubygems_version = "2.6.8".freeze
72
+ s.rubygems_version = "2.5.2".freeze
72
73
  s.summary = "RabbitMQ RPC/PubSub Library".freeze
73
74
 
74
75
  if s.respond_to? :specification_version then
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: skein
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Tadman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-07 00:00:00.000000000 Z
11
+ date: 2016-12-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: birling
@@ -85,6 +85,7 @@ files:
85
85
  - config/.gitignore
86
86
  - config/skein.yml.example
87
87
  - lib/skein.rb
88
+ - lib/skein/adapter.rb
88
89
  - lib/skein/client.rb
89
90
  - lib/skein/client/publisher.rb
90
91
  - lib/skein/client/rpc.rb
@@ -141,7 +142,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
142
  version: '0'
142
143
  requirements: []
143
144
  rubyforge_project:
144
- rubygems_version: 2.6.8
145
+ rubygems_version: 2.5.2
145
146
  signing_key:
146
147
  specification_version: 4
147
148
  summary: RabbitMQ RPC/PubSub Library