cloudist 0.4.4 → 0.5.0

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.
@@ -1,22 +1,22 @@
1
1
  module Cloudist
2
2
  class Publisher
3
-
3
+
4
4
  class << self
5
5
  def enqueue(queue_name, data)
6
6
  payload = Cloudist::Payload.new(data)
7
-
7
+
8
8
  queue = Cloudist::JobQueue.new(queue_name)
9
-
9
+
10
10
  queue.setup
11
-
11
+
12
12
  # send_message = proc {
13
13
  queue.publish(payload)
14
14
  # }
15
15
  # EM.next_tick(&send_message)
16
-
16
+
17
17
  return Job.new(payload)
18
18
  end
19
19
  end
20
-
20
+
21
21
  end
22
22
  end
@@ -1,19 +1,19 @@
1
1
  module Cloudist
2
2
  class UnknownReplyTo < RuntimeError; end
3
3
  class ExpiredMessage < RuntimeError; end
4
-
4
+
5
5
  module Queues
6
6
  class BasicQueue
7
7
  attr_reader :queue_name, :options
8
8
  attr_reader :queue, :exchange, :channel, :prefetch
9
-
9
+
10
10
  alias :q :queue
11
11
  alias :ex :exchange
12
12
  alias :mq :channel
13
-
13
+
14
14
  def initialize(queue_name, options = {})
15
15
  @prefetch ||= options.delete(:prefetch) || 1
16
-
16
+
17
17
  options = {
18
18
  :auto_delete => true,
19
19
  :durable => false,
@@ -21,28 +21,28 @@ module Cloudist
21
21
  }.update(options)
22
22
 
23
23
  @queue_name, @options = queue_name, options
24
-
24
+
25
25
  setup
26
26
  end
27
-
27
+
28
28
  def inspect
29
29
  "<#{self.class.name} queue_name=#{queue_name}>"
30
30
  end
31
31
 
32
32
  def setup
33
33
  return if @setup.eql?(true)
34
-
34
+
35
35
  @channel ||= AMQP::Channel.new(Cloudist.connection) do
36
- channel.prefetch(self.prefetch, false) if self.prefetch.present?
36
+ channel.prefetch(self.prefetch, false) if self.prefetch
37
37
  end
38
-
38
+
39
39
  @queue = @channel.queue(queue_name, options)
40
-
40
+
41
41
  setup_exchange
42
-
42
+
43
43
  @setup = true
44
44
  end
45
-
45
+
46
46
  def setup_exchange
47
47
  @exchange = channel.direct("")
48
48
  end
@@ -61,13 +61,13 @@ module Cloudist
61
61
  s += " exchange=#{exchange.name}" if exchange
62
62
  s
63
63
  end
64
-
64
+
65
65
  def subscribe(&block)
66
66
  queue.subscribe(:ack => true) do |queue_header, encoded_message|
67
67
  # next if Cloudist.closing?
68
68
 
69
69
  request = Cloudist::Request.new(self, encoded_message, queue_header)
70
-
70
+
71
71
  handle_request = proc {
72
72
  begin
73
73
  raise Cloudist::ExpiredMessage if request.expired?
@@ -86,11 +86,11 @@ module Cloudist
86
86
  # log.debug("Finished Job in #{finished - request.start} seconds")
87
87
  end
88
88
  }
89
-
89
+
90
90
  handle_ack = proc {
91
91
  request.ack
92
92
  }
93
-
93
+
94
94
  EM.defer(handle_request, handle_ack)
95
95
  end
96
96
  log.info "AMQP Subscribed: #{tag}"
@@ -128,4 +128,4 @@ module Cloudist
128
128
  end
129
129
  end
130
130
  end
131
- end
131
+ end
@@ -1,26 +1,26 @@
1
1
  module Cloudist
2
2
  class JobQueue < Cloudist::Queues::BasicQueue
3
-
3
+
4
4
  def initialize(queue_name, options={})
5
5
  options[:auto_delete] = false
6
6
  options[:nowait] = false
7
-
7
+
8
8
  @prefetch = Cloudist.worker_prefetch
9
9
  puts "Prefetch: #{@prefetch}"
10
10
  super(queue_name, options)
11
11
  end
12
-
12
+
13
13
  # def initialize(queue_name, options={})
14
14
  # @prefetch = 1
15
15
  # # opts[:auto_delete] = false
16
- #
16
+ #
17
17
  # super(queue_name, options)
18
18
  # end
19
-
19
+
20
20
  # def setup_exchange
21
21
  # @exchange = channel.direct(queue_name)
22
22
  # queue.bind(exchange)
23
23
  # end
24
-
24
+
25
25
  end
26
26
  end
@@ -3,23 +3,23 @@ module Cloudist
3
3
  def initialize(queue_name, options={})
4
4
  options[:auto_delete] = true
5
5
  options[:nowait] = false
6
-
6
+
7
7
  @prefetch = Cloudist.listener_prefetch
8
-
8
+
9
9
  super(queue_name, options)
10
10
  end
11
-
11
+
12
12
  # def subscribe(&block)
13
13
  # super do |request|
14
14
  # yield request if block_given?
15
15
  # teardown
16
16
  # end
17
17
  # end
18
-
18
+
19
19
  # def teardown
20
20
  # queue.delete
21
21
  # super
22
22
  # end
23
-
23
+
24
24
  end
25
25
  end
@@ -1,7 +1,7 @@
1
1
  module Cloudist
2
2
  class Request
3
3
  include Cloudist::Encoding
4
-
4
+
5
5
  attr_reader :queue_header, :qobj, :payload, :start, :headers, :body
6
6
 
7
7
  def initialize(queue, encoded_body, queue_header)
@@ -9,13 +9,13 @@ module Cloudist
9
9
 
10
10
  @body = decode(encoded_body)
11
11
  @headers = parse_custom_headers(queue_header)
12
-
12
+
13
13
  @payload = Cloudist::Payload.new(encoded_body, queue_header.headers.dup)
14
14
  @headers = @payload.headers
15
15
 
16
16
  @start = Time.now.utc.to_f
17
17
  end
18
-
18
+
19
19
  def parse_custom_headers(amqp_headers)
20
20
  h = amqp_headers.headers.dup
21
21
 
@@ -26,7 +26,7 @@ module Cloudist
26
26
 
27
27
  h
28
28
  end
29
-
29
+
30
30
  def for_message
31
31
  [body.dup, queue_header.headers.dup]
32
32
  end
@@ -42,7 +42,7 @@ module Cloudist
42
42
  def mq
43
43
  qobj.channel
44
44
  end
45
-
45
+
46
46
  def channel
47
47
  mq
48
48
  end
@@ -22,7 +22,7 @@ module Cloudist
22
22
  def generate_name_for_instance(name)
23
23
  "#{name}.#{Socket.gethostname}"
24
24
  end
25
-
25
+
26
26
  # DEPRECATED
27
27
  def generate_reply_to(name)
28
28
  "#{reply_prefix(name)}.#{generate_sym}"
@@ -40,15 +40,15 @@ module Cloudist
40
40
  ]
41
41
  "%04x%04x%04x%04x%04x%06x%06x" % values
42
42
  end
43
-
43
+
44
44
  def encode_message(object)
45
45
  Marshal.dump(object).to_s
46
46
  end
47
-
47
+
48
48
  def decode_message(string)
49
49
  Marshal.load(string)
50
50
  end
51
-
51
+
52
52
  def decode_json(string)
53
53
  if defined? ActiveSupport::JSON
54
54
  ActiveSupport::JSON.decode string
@@ -56,6 +56,6 @@ module Cloudist
56
56
  JSON.load string
57
57
  end
58
58
  end
59
-
59
+
60
60
  end
61
61
  end
@@ -1,37 +1,37 @@
1
1
  module Cloudist
2
2
  class Worker
3
-
3
+
4
4
  attr_reader :job, :queue, :payload
5
-
5
+
6
6
  def initialize(job, queue)
7
7
  @job, @queue, @payload = job, queue, job.payload
8
-
8
+
9
9
  # Do custom initialization
10
10
  self.setup if self.respond_to?(:setup)
11
11
  end
12
-
12
+
13
13
  def data
14
14
  job.data
15
15
  end
16
-
16
+
17
17
  def headers
18
18
  job.headers
19
19
  end
20
-
20
+
21
21
  def id
22
22
  job.id
23
23
  end
24
-
24
+
25
25
  def process
26
26
  raise NotImplementedError, "Your worker class must subclass this method"
27
27
  end
28
-
28
+
29
29
  def log
30
30
  Cloudist.log
31
31
  end
32
-
32
+
33
33
  end
34
-
34
+
35
35
  class GenericWorker < Worker
36
36
  def process(&block)
37
37
  instance_eval(&block)
@@ -6,28 +6,28 @@ describe "Cloudist" do
6
6
  overload_amqp
7
7
  reset_broker
8
8
  end
9
-
9
+
10
10
  it "should create a queue and exchange" do
11
11
  # MQ.stubs(:direct).with(:name).returns(true)
12
12
  @mq = mock("MQ")
13
13
  @exchange = mock("MQ Exchange")
14
14
  @queue = mock("MQ Queue")
15
-
15
+
16
16
  @queue.expects(:bind).with(@exchange)
17
17
  # @mq.expects(:queue).with("make.sandwich")
18
-
18
+
19
19
  bq = Cloudist::Queues::BasicQueue.new("make.sandwich")
20
- bq.stubs(:q).returns(@queue)
21
- bq.stubs(:mq).returns(@mq)
22
- bq.stubs(:ex).returns(@exchange)
23
-
20
+ bq.stub(:q).and_return(@queue)
21
+ bq.stub(:mq).and_return(@mq)
22
+ bq.stub(:ex).and_return(@exchange)
23
+
24
24
  bq.setup
25
-
25
+
26
26
  bq.q.should_not be_nil
27
27
  bq.ex.should_not be_nil
28
28
  bq.mq.should_not be_nil
29
29
  end
30
-
30
+
31
31
  end
32
-
32
+
33
33
  end
@@ -4,20 +4,20 @@ describe Cloudist::Job do
4
4
  before(:each) do
5
5
  @payload = Cloudist::Payload.new({:bread => 'white'})
6
6
  end
7
-
7
+
8
8
  it "should be constructable with payload" do
9
9
  job = Cloudist::Job.new(@payload)
10
10
  job.payload.should == @payload
11
11
  end
12
-
12
+
13
13
  it "should be constructable with payload and return ID" do
14
14
  job = Cloudist::Job.new(@payload)
15
15
  job.id.should == @payload.id
16
16
  end
17
-
17
+
18
18
  it "should be constructable with payload and return data" do
19
19
  job = Cloudist::Job.new(@payload)
20
20
  job.data.should == @payload.body
21
21
  end
22
-
22
+
23
23
  end
@@ -2,22 +2,22 @@ require File.expand_path(File.dirname(__FILE__) + '../../spec_helper')
2
2
 
3
3
  describe Cloudist::Payload do
4
4
  include Cloudist::Encoding
5
-
5
+
6
6
  it "should accept a hash for data" do
7
7
  pl = Cloudist::Payload.new({:bread => 'white'})
8
8
  pl.body.bread.should == "white"
9
9
  end
10
-
10
+
11
11
  it "should accept encoded message" do
12
12
  pl = Cloudist::Payload.new(encode({:bread => 'white'}))
13
13
  pl.body.bread.should == "white"
14
14
  end
15
-
15
+
16
16
  it "should retrieve id from headers" do
17
17
  pl = Cloudist::Payload.new({:bread => 'white'}, {:message_id => "12345"})
18
18
  pl.id.should == "12345"
19
19
  end
20
-
20
+
21
21
  it "should prepare headers" do
22
22
  payload = Cloudist::Payload.new({:bread => 'white'})
23
23
  payload.body.bread.should == "white"
@@ -27,52 +27,52 @@ describe Cloudist::Payload do
27
27
  payload.headers.has_key?("published_on").should be_true
28
28
  payload.headers.has_key?("message_id").should be_true
29
29
  end
30
-
30
+
31
31
  it "should extract published_on from data" do
32
32
  time = Time.now.to_f
33
33
  payload = Cloudist::Payload.new({:bread => 'white', :timestamp => time})
34
34
  payload.headers[:published_on].should == time
35
35
  end
36
-
36
+
37
37
  it "should not override timestamp if already present in headers" do
38
38
  time = (Time.now.to_f - 10.0)
39
39
  payload = Cloudist::Payload.new({:bread => 'white'}, {:published_on => time})
40
40
  payload.headers[:published_on].should == time
41
41
  end
42
-
42
+
43
43
  it "should override timestamp if not present" do
44
44
  payload = Cloudist::Payload.new({:bread => 'white'})
45
45
  payload.headers[:published_on].should be_within(0.1).of Time.now.to_f
46
46
  payload.timestamp.should be_within(0.1).of Time.now.to_f
47
47
  end
48
-
48
+
49
49
  it "should parse custom headers" do
50
50
  payload = Cloudist::Payload.new(Marshal.dump({:bread => 'white'}), {:published_on => 12345, :message_id => "foo"})
51
51
  payload.headers.to_hash.should == { "published_on"=>12345, "message_id"=>"foo", "ttl"=>300 }
52
52
  end
53
-
53
+
54
54
  it "should create a unique event hash" do
55
55
  payload = Cloudist::Payload.new({:bread => 'white'})
56
56
  payload.id.size.should == 36
57
57
  end
58
-
58
+
59
59
  it "should not create a new message_id unless it doesn't have one" do
60
60
  payload = Cloudist::Payload.new({:bread => 'white'})
61
61
  payload.id.size.should == 36
62
62
  payload = Cloudist::Payload.new({:bread => 'white'}, {:message_id => 'foo'})
63
63
  payload.id.should == 'foo'
64
64
  end
65
-
65
+
66
66
  it "should format payload for sending" do
67
67
  payload = Cloudist::Payload.new({:bread => 'white'}, {:message_id => 'foo', :message_type => 'reply'})
68
68
  body, popts = payload.to_a
69
69
  headers = popts[:headers]
70
-
70
+
71
71
  body.should == encode(Hashie::Mash.new({:bread => 'white'}))
72
72
  headers[:ttl].should == "300"
73
73
  headers[:message_type].should == 'reply'
74
74
  end
75
-
76
-
77
-
78
- end
75
+
76
+
77
+
78
+ end