masstransit 0.2 → 0.2.2

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.
@@ -0,0 +1,13 @@
1
+ require 'rubygems'
2
+ require 'active_support' unless defined?(ActiveSupport)
3
+
4
+ here = File.expand_path(File.dirname(__FILE__))
5
+
6
+ $LOAD_PATH << "#{here}/masstransit"
7
+ require 'bus'
8
+ require 'config'
9
+ require 'message'
10
+ require 'serializer'
11
+ require 'envelope'
12
+ require 'transports/amqp'
13
+ require 'urn'
@@ -0,0 +1,84 @@
1
+ module MassTransit
2
+ #The bus abstracts the desired transportation, and manages the callbacks
3
+ #orchestrates the threading
4
+ #
5
+ #three main queues (data, control, poison)
6
+ class Bus
7
+ def initialize(conf)
8
+ @subscriptions = {}
9
+ @serializer = conf.serializer
10
+ @transport = conf.transport
11
+ @queue = conf.queue
12
+
13
+ @transport.open(conf)
14
+ end
15
+
16
+ #this will register an exchange in rabbit for the 'message_name'
17
+ #and then bind the queue to that exchange. it then sets
18
+ # the subscriptions[message_name] to the callback provided
19
+ def subscribe(message_name, &block)
20
+ @subscriptions = {} if @subscriptions.nil?
21
+ consumers = @subscriptions[message_name]
22
+ consumers = [] if consumers.nil?
23
+ consumers << block
24
+ @subscriptions[message_name] = consumers
25
+ @transport.bind message_name
26
+ end
27
+
28
+ #this will unregister the queue with the exchange in rabbitmq
29
+ #for the message_name. It then removes the callbacks in the
30
+ #subscriptions
31
+ def unsubscribe(message_name)
32
+ @transport.unbind(message_name, @queue)
33
+
34
+ #has key check
35
+ @subscriptions.delete(message_name)
36
+
37
+ end
38
+
39
+ #tells the bus to start listening for messages
40
+ #this method blocks forver. Need to implement
41
+ #better ctrl-c support
42
+ def start()
43
+ #start listening
44
+ @transport.monitor do |rmsg|
45
+ consume(rmsg)
46
+ end
47
+ end
48
+
49
+ def close()
50
+
51
+ end
52
+
53
+ #this will publish the message object to an exchange in rabbitmq
54
+ #that is equal to the message class name. this is a direct concept
55
+ #from .net and should be adopted into a more ruby manner
56
+ def publish(message)
57
+ envelope = @transport.create_message(message, @serializer)
58
+ data = @serializer.serialize(envelope)
59
+
60
+ @transport.publish(envelope.MessageType, data) #exchange?
61
+ end
62
+
63
+ #takes a rabbitmq message, strips off the noise and gets back to an
64
+ #envelope
65
+ def consume(rmsg)
66
+ data = @transport.get_message(rmsg)
67
+ #payload is a string
68
+ env = @serializer.deserialize data
69
+ puts 'oeuaoeusatoehuntsaoheuntsahoeusnth'
70
+ puts env
71
+ deliver(env)
72
+ end
73
+
74
+ #for local distribution
75
+ def deliver(env)
76
+ consumers = @subscriptions[env.MessageType]
77
+ consumers = [] if consumers.nil?
78
+ consumers.each do |c|
79
+ obj = @serializer.deserialize(env.Message)
80
+ c.call obj
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,55 @@
1
+ require 'yaml'
2
+ require 'transports/amqp'
3
+ require 'serializer'
4
+
5
+ module MassTransit
6
+ #A class that groups all of the configuration options and provides defaults
7
+ #Currently AMQP is the only transport option
8
+ class Config
9
+ attr_accessor :server
10
+ attr_accessor :port
11
+ attr_accessor :vdir
12
+ attr_accessor :user
13
+ attr_accessor :password
14
+ attr_accessor :insist
15
+ attr_accessor :transport
16
+ attr_accessor :serializer
17
+ attr_accessor :queue
18
+
19
+ def initialize()
20
+ @server = 'localhost'
21
+ @port = 5672
22
+ @vdir = '/'
23
+ @user = 'guest'
24
+ @password = 'guest'
25
+ @insist = true
26
+ @transport = Amqp.new()
27
+ @serializer = Serializer.new
28
+ @queue = 'default_queue'
29
+ end
30
+ end
31
+
32
+ # Sample Config File
33
+ # ---
34
+ # server : localhost
35
+ # port : 5672
36
+ # vdir : /
37
+ # user : guest
38
+ # password : guest
39
+ # insist: true def load_config(file_name)
40
+ def MassTransit.load_config(file_name)
41
+ o = YAML::load_file(file_name)
42
+ cfg = Config.new
43
+
44
+ cfg.server = o['server']
45
+ cfg.port = o['port']
46
+ cfg.vdir = o['vdir']
47
+ cfg.user = o['user']
48
+ cfg.password = o['password']
49
+ cfg.insist = o['insist']
50
+ cfg.queue = o['queue']
51
+
52
+ return cfg
53
+ end
54
+
55
+ end
@@ -0,0 +1,15 @@
1
+ module MassTransit
2
+ #a simple class to wrap the message and name
3
+ class Envelope
4
+ attr_accessor :MessageType
5
+ attr_accessor :Message
6
+
7
+ def initialize()
8
+ end
9
+
10
+ # def initialize(message_name, body)
11
+ # @message_name = message_name
12
+ # @body = body
13
+ # end
14
+ end
15
+ end
File without changes
@@ -0,0 +1,26 @@
1
+ require 'ostruct'
2
+
3
+ module MassTransit
4
+
5
+ #creates a method missing style dictionary for when
6
+ #i don't have the actual type availible
7
+ class Message
8
+ attr_accessor :hash
9
+
10
+ def initialize(hash)
11
+ @hash = hash
12
+ @o = OpenStruct.new hash
13
+ end
14
+
15
+ def method_missing(name, *args)
16
+ value = @o.send name, args
17
+ if value.class == Hash
18
+ value = Message.new value
19
+ end
20
+ return value unless value.nil?
21
+ super
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,25 @@
1
+ require 'active_support'
2
+ require 'ostruct'
3
+ # may want to write my own to change the json_class bit
4
+ #http://flori.github.com/json/doc/classes/Object.html#method-i-to_json
5
+ #look at the source and hack! whoot whoot
6
+
7
+ module MassTransit
8
+
9
+ class Serializer
10
+ def serialize(env)
11
+ #enforce that env is an Envelope
12
+ return ActiveSupport::JSON.encode env
13
+ end
14
+
15
+ #returns an Envelope
16
+ def deserialize(data)
17
+ result = ActiveSupport::JSON.decode(data)
18
+
19
+ result = MassTransit::Message.new(result)
20
+
21
+ result
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1,84 @@
1
+ require 'bunny'
2
+
3
+ module MassTransit
4
+ #The wrapper class on top of AMQP, that provides the standard
5
+ #masstransit 'transport' api
6
+ class Amqp
7
+
8
+ #opens a connection to the Amqp server
9
+ def open(config)
10
+ @client = Bunny.new(
11
+ :logging=>true,
12
+ :host => config.server,
13
+ :port => config.port,
14
+ :user => config.user,
15
+ :pass => config.password,
16
+ :vhost => config.vdir,
17
+ :insist => config.insist
18
+ )
19
+ @queue = config.queue
20
+ @client.start
21
+ end
22
+
23
+ #closes the connection to the Amqp server
24
+ def close()
25
+ @client.close()
26
+ end
27
+
28
+ #declares a queue on the server
29
+ def queue_declare(name)
30
+ @client.queue(name)
31
+ end
32
+
33
+ def queue_delete(name)
34
+ #how to?
35
+ end
36
+
37
+ #binds the queue to the exchange
38
+ def bind(exchange)
39
+ ex = @client.exchange(exchange, :type=>:fanout, :durable=>true)
40
+ q = @client.queue(@queue)
41
+ q.bind(ex)
42
+ end
43
+
44
+ #unbnids the queue from the exchange
45
+ def unbind(queue, exchange)
46
+ end
47
+
48
+ #creates a transport ready message object
49
+ def create_message(data, serializer)
50
+ msg_name = data.class.name.gsub("::",".")
51
+ msg = data
52
+
53
+ env = Envelope.new
54
+ env.MessageType = msg_name
55
+ #this needs to be a string for .net
56
+ env.Message = serializer.serialize(msg)
57
+
58
+ return env
59
+ end
60
+
61
+ def get_message(rmsg)
62
+ return rmsg[:payload]
63
+ end
64
+
65
+ def monitor(&block)
66
+ #basic consume / pop loop here
67
+ q = @client.queue(@queue)
68
+ q.subscribe(:consumer_tag => 'testtag1', :timeout => 30) do |msg|
69
+ block.call msg
70
+ end
71
+
72
+ end
73
+
74
+ #pushes the message onto the exchange
75
+ def send(queue, data)
76
+ @client.queue(queue).publish(data)
77
+ end
78
+
79
+ def publish(exchange, data)
80
+ ex = @client.exchange(exchange, :type=>:fanout, :durable=>true)
81
+ ex.publish(data)
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,14 @@
1
+ module MassTransit
2
+
3
+ class Urn
4
+ attr_accessor :kind
5
+
6
+ def initialize(args)
7
+ if args.class == Class
8
+ args = args.to_s.sub '::',':'
9
+ end
10
+ @kind = args.sub '.',':'
11
+ end
12
+
13
+ end
14
+ end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: masstransit
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15
5
- prerelease: false
4
+ hash: 19
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- version: "0.2"
9
+ - 2
10
+ version: 0.2.2
10
11
  platform: ruby
11
12
  authors:
12
13
  - ACM,PBG,LEGO
@@ -14,7 +15,7 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2011-01-09 00:00:00 -06:00
18
+ date: 2011-01-12 00:00:00 -06:00
18
19
  default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
@@ -39,8 +40,16 @@ extensions: []
39
40
 
40
41
  extra_rdoc_files: []
41
42
 
42
- files: []
43
-
43
+ files:
44
+ - ./lib/masstransit/bus.rb
45
+ - ./lib/masstransit/config.rb
46
+ - ./lib/masstransit/envelope.rb
47
+ - ./lib/masstransit/exceptions.rb
48
+ - ./lib/masstransit/message.rb
49
+ - ./lib/masstransit/serializer.rb
50
+ - ./lib/masstransit/transports/amqp.rb
51
+ - ./lib/masstransit/urn.rb
52
+ - ./lib/masstransit.rb
44
53
  has_rdoc: true
45
54
  homepage: http://www.masstransit.com
46
55
  licenses: []
@@ -71,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
71
80
  requirements: []
72
81
 
73
82
  rubyforge_project: masstransit
74
- rubygems_version: 1.3.7
83
+ rubygems_version: 1.4.2
75
84
  signing_key:
76
85
  specification_version: 3
77
86
  summary: a simple message framework