lolitra 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Lolitra
2
2
 
3
- TODO: Write a gem description
3
+ Amqp and Faye event bus
4
4
 
5
5
  ## Installation
6
6
 
@@ -18,7 +18,55 @@ Or install it yourself as:
18
18
 
19
19
  ## Usage
20
20
 
21
- TODO: Write usage instructions here
21
+ Create an event bus on initializers
22
+
23
+ Lolitra::AmqpBus.new(
24
+ :exchange => "exchangetest",
25
+ :queue_prefix => "my_prefix_",
26
+ :host => "127.0.0.1",
27
+ :port => 5672,
28
+ :user => "guest",
29
+ :pass => "guest",
30
+ :pull_subscribers => [DevicesHandler, FoldersHandler, UsersHandler]
31
+ )
32
+
33
+ Create messages
34
+
35
+ class DeviceCreated
36
+ include Lolitra::Message
37
+
38
+ attr_accessor :id, :name
39
+
40
+ message_key 'assets.device.created'
41
+ end
42
+
43
+ class DeviceMoved
44
+ include Lolitra::Message
45
+
46
+ attr_accessor :id
47
+
48
+ message_key 'assets.device.moved'
49
+ end
50
+
51
+ Create a message handler
52
+
53
+ class DevicesHandler
54
+ include Lolitra::MessageHandler
55
+
56
+ message_handler DeviceCreated, :id
57
+ message_handler DeviceMoved, :id
58
+
59
+ stateful false
60
+
61
+ def device_created(message)
62
+ Device.new({:id => message.id})
63
+ end
64
+
65
+ def deivce_moved(message)
66
+ Device.move({:id => message.id})
67
+ end
68
+
69
+ end
22
70
 
23
71
  ## Contributing
24
72
 
@@ -18,6 +18,15 @@ module Lolitra
18
18
  @@logger = new_logger
19
19
  end
20
20
 
21
+ def self.log_exception(e)
22
+ logger.error(e.message)
23
+ logger.error(e.backtrace.join("\n\t"))
24
+ end
25
+
26
+ def self.publish(message)
27
+ Lolitra::MessageHandlerManager.publish(message)
28
+ end
29
+
21
30
  module MessageHandler
22
31
  module Helpers
23
32
  def self.underscore(arg)
@@ -56,13 +65,10 @@ module Lolitra
56
65
  end
57
66
 
58
67
  def handle(message)
59
- Lolitra::logger.debug("Message recived: #{message.class.message_key}")
60
- Lolitra::logger.debug("#{message}")
61
68
  begin
62
69
  get_handler(message).handle(message)
63
- rescue NoMethodError => e
64
- raise NoHandlerMessageException.new(self, message) if e.message == "undefined method `handle' for nil:NilClass"
65
- raise
70
+ rescue => e
71
+ Lolitra::log_exception(e)
66
72
  end
67
73
  end
68
74
 
@@ -204,7 +210,9 @@ module Lolitra
204
210
 
205
211
  def initialize(hash={})
206
212
  super()
207
- self.replace(hash)
213
+ hash.keys.each do |key|
214
+ self.send "#{key}=", hash[key] if self.respond_to? "#{key}="
215
+ end
208
216
  end
209
217
 
210
218
  def marshall
@@ -222,6 +230,8 @@ module Lolitra
222
230
  def subscribe(message_class, handler_class)
223
231
  EM::next_tick do
224
232
  @socketClient.subscribe(message_class.message_key) do |payload|
233
+ Lolitra::logger.debug("Message recived:")
234
+ Lolitra::logger.debug("#{payload}")
225
235
  handler_class.handle(message_class.unmarshall(payload))
226
236
  end
227
237
  end
@@ -238,14 +248,28 @@ module Lolitra
238
248
  attr_accessor :exchange
239
249
 
240
250
  def initialize(hash = {})
241
- params = hash.reject { |key, value| !value }
251
+ Lolitra::MessageHandlerManager.bus = self
252
+
253
+ @channels = {}
254
+ @params = hash.reject { |key, value| !value }
242
255
  raise "no :exchange specified" unless hash[:exchange]
243
256
 
244
257
  self.queue_prefix = hash[:queue_prefix]||""
245
-
246
258
  AMQP::Utilities::EventLoopHelper.run do
247
- self.connection = AMQP.connect(params)
248
- self.exchange = AMQP::Channel.new(self.connection).topic(params[:exchange], :durable => true)
259
+ self.connection = AMQP.start(@params) do |connection|
260
+ channel = create_channel(connection) do |channel|
261
+ begin
262
+ self.exchange = channel.topic(@params[:exchange], :durable => true)
263
+
264
+ @params[:pull_subscribers].each do |handler|
265
+ Lolitra::MessageHandlerManager.register_pull_subscriber(handler)
266
+ end
267
+ rescue => e
268
+ Lolitra::logger.debug("error")
269
+ Lolitra::log_exception(e)
270
+ end
271
+ end
272
+ end
249
273
  end
250
274
  end
251
275
 
@@ -254,21 +278,51 @@ module Lolitra
254
278
  end
255
279
 
256
280
  def pull_subscribe(message_class, handler_class)
257
- create_queue(message_class, handler_class, {:durable => true}, queue_prefix + MessageHandler::Helpers.underscore(handler_class.name))
281
+ create_queue(message_class, handler_class, {:durable => true})
258
282
  end
259
283
 
260
284
  def publish(message)
285
+ #TODO: if exchange channel is closed doesn't log anything
261
286
  self.exchange.publish(message.marshall, :routing_key => message.class.message_key, :timestamp => Time.now.to_i)
262
287
  end
263
288
 
264
289
  private
265
- def create_queue(message_class, handler_class, options, queue_name)
266
- EM.next_tick do
267
- channel = AMQP::Channel.new(self.connection)
268
- channel.prefetch(1).queue(queue_name, options).bind(self.exchange, :routing_key => message_class.message_key).subscribe do |info, payload|
269
- message_class_tmp = handler_class.handlers[info.routing_key][0]
270
- handler_class.handle(message_class_tmp.unmarshall(payload))
290
+ def create_channel(connection, &block)
291
+ channel = AMQP::Channel.new(connection) do
292
+ channel.on_error do |channel, close|
293
+ Lolitra::logger.error("Channel error: #{channel}")
294
+ Lolitra::logger.error(close)
295
+ end
296
+ block.call(channel)
297
+ end
298
+ channel
299
+ end
300
+
301
+ def create_queue(message_class, handler_class, options)
302
+ begin
303
+ queue_name = queue_prefix + MessageHandler::Helpers.underscore(handler_class.name)
304
+
305
+ create_channel(self.connection) do |channel|
306
+ channel.queue(queue_name, options).bind(self.exchange, :routing_key => message_class.message_key)
307
+ channel.close
308
+ end
309
+
310
+ if !@channels[queue_name] #Only one subscriber by queue_name
311
+ @channels[queue_name] = create_channel(self.connection) do |channel|
312
+ channel.prefetch(1).queue(queue_name, options).subscribe do |info, payload|
313
+ begin
314
+ Lolitra::logger.debug("Message recived: #{info.routing_key}")
315
+ Lolitra::logger.debug("#{payload}")
316
+ message_class_tmp = handler_class.handlers[info.routing_key][0]
317
+ handler_class.handle(message_class_tmp.unmarshall(payload))
318
+ rescue => e
319
+ Lolitra::log_exception(e)
320
+ end
321
+ end
322
+ end
271
323
  end
324
+ rescue => e
325
+ Lolitra::log_exception(e)
272
326
  end
273
327
  end
274
328
  end
@@ -1,3 +1,3 @@
1
1
  module Lolitra
2
- VERSION = "0.1.3"
2
+ VERSION = "0.2.0"
3
3
  end
data/lolitra.gemspec CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |gem|
16
16
  gem.version = Lolitra::VERSION
17
17
 
18
18
  gem.add_development_dependency("rspec")
19
- gem.add_dependency("amqp")
19
+ gem.add_dependency("amqp", ">= 0.8.4")
20
20
  gem.add_dependency("json")
21
21
  gem.add_dependency("log4r")
22
22
  gem.add_dependency("faye")
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
8
- - 3
9
- version: 0.1.3
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Hugo Freire
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2012-12-23 00:00:00 -05:00
17
+ date: 2015-02-20 00:00:00 +01:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -40,7 +40,9 @@ dependencies:
40
40
  - !ruby/object:Gem::Version
41
41
  segments:
42
42
  - 0
43
- version: "0"
43
+ - 8
44
+ - 4
45
+ version: 0.8.4
44
46
  type: :runtime
45
47
  version_requirements: *id002
46
48
  - !ruby/object:Gem::Dependency