skein 0.3.0 → 0.3.1

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.
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