queuel 0.0.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.
@@ -0,0 +1,40 @@
1
+ require 'queuel/iron_mq/poller'
2
+ module Queuel
3
+ module IronMq
4
+ class Queue
5
+ def initialize(client, queue_name)
6
+ self.client = client
7
+ self.name = queue_name
8
+ end
9
+
10
+ # For IronMQ it should just be (message)
11
+ def push(*args)
12
+ queue_connection.post *args
13
+ end
14
+
15
+ def pop(*args, &block)
16
+ bare_message = queue_connection.get(*args)
17
+ unless bare_message.nil?
18
+ Message.new_from_iron_mq_object(bare_message).tap { |message|
19
+ if block_given? && !message.nil?
20
+ yield message
21
+ message.delete
22
+ end
23
+ }
24
+ end
25
+ end
26
+
27
+ def receive(options = {}, &block)
28
+ Poller.new(self, options, block).poll
29
+ end
30
+
31
+ private
32
+ attr_accessor :client
33
+ attr_accessor :name
34
+
35
+ def queue_connection
36
+ @queue_connection ||= client.queue(name)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,12 @@
1
+ module Queuel
2
+ module Null
3
+ class Engine
4
+ def initialize(*)
5
+ end
6
+
7
+ def queue(*)
8
+ Queue.new
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,21 @@
1
+ require 'forwardable'
2
+ module Queuel
3
+ module Null
4
+ class Message
5
+ def initialize(id, body, queue = nil)
6
+ self.id = id
7
+ self.body = body
8
+ self.queue = queue
9
+ end
10
+
11
+ attr_reader :id
12
+ attr_reader :queue
13
+ attr_reader :body
14
+
15
+ private
16
+ attr_writer :id
17
+ attr_writer :queue
18
+ attr_writer :body
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,120 @@
1
+ require 'timeout'
2
+ module Queuel
3
+ module Null
4
+ class Poller
5
+ # q is here for similar API, but not needed in THIS
6
+ # class
7
+ def initialize(q, options, block)
8
+ self.options = options || {}
9
+ self.block = block
10
+ self.tries = 0
11
+ self.continue_looping = true
12
+ end
13
+
14
+ def poll
15
+ choose_looper do |msg|
16
+ if msg.nil?
17
+ tried
18
+ quit_looping! if break_if_nil? || maxed_tried?
19
+ sleep(sleep_time)
20
+ end
21
+ !msg.nil?
22
+ end
23
+ end
24
+
25
+ protected
26
+ attr_accessor :tries
27
+
28
+ private
29
+ attr_accessor :queue
30
+ attr_accessor :args
31
+ attr_accessor :options
32
+ attr_accessor :block
33
+ attr_accessor :continue_looping
34
+
35
+ def choose_looper(&loop_block)
36
+ timeout? ? timeout_looper(loop_block) : looper(loop_block)
37
+ end
38
+
39
+ def timeout_looper(loop_block)
40
+ Timeout.timeout(timeout) { looper(loop_block) }
41
+ rescue Timeout::Error
42
+ false
43
+ end
44
+
45
+ def looper(loop_block)
46
+ while continue_looping? do
47
+ loop_block.call(pop_new_message)
48
+ end
49
+ end
50
+
51
+ def continue_looping?
52
+ !!continue_looping
53
+ end
54
+
55
+ def quit_looping!
56
+ self.continue_looping = false
57
+ end
58
+
59
+ def timeout
60
+ options[:poll_timeout].to_i
61
+ end
62
+
63
+ def timeout?
64
+ timeout > 0
65
+ end
66
+
67
+ def pop_new_message
68
+ nil
69
+ end
70
+
71
+ def start_sleep_time
72
+ 0.1
73
+ end
74
+
75
+ def sleep_time
76
+ tries < 30 ? (start_sleep_time * tries) : 3
77
+ end
78
+
79
+ def reset_tries
80
+ self.tries = 0
81
+ end
82
+
83
+ def maxed_tried?
84
+ tries >= max_fails if max_fails_given?
85
+ end
86
+
87
+ def max_fails_given?
88
+ max_fails > 0
89
+ end
90
+
91
+ def max_fails
92
+ options[:max_consecutive_fails].to_i
93
+ end
94
+
95
+ def tried
96
+ self.tries += 1
97
+ end
98
+
99
+ def break_if_nil?
100
+ !!options.fetch(:break_if_nil, false)
101
+ end
102
+
103
+ def option_keys
104
+ %w[break_if_nil poll_timeout max_consecutive_fails]
105
+ end
106
+
107
+ def my_options
108
+ options.select { |key,_| option_keys.include? key.to_s }
109
+ end
110
+
111
+ def built_options
112
+ options.merge default_args # intentional direction, force defaults
113
+ end
114
+
115
+ def default_args
116
+ { n: 1 }
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,20 @@
1
+ require 'queuel/null/poller'
2
+ module Queuel
3
+ module Null
4
+ class Queue
5
+ def initialize(*)
6
+ end
7
+
8
+ # For IronMQ it should just be (message)
9
+ def push(*)
10
+ end
11
+
12
+ def pop(*args, &block)
13
+ end
14
+
15
+ def receive(options = {}, &block)
16
+ Poller.new(options, block).poll
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,3 @@
1
+ module Queuel
2
+ VERSION = "0.0.1"
3
+ end
data/queuel.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'queuel/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "queuel"
8
+ spec.version = Queuel::VERSION
9
+ spec.authors = ["Jon Phenow"]
10
+ spec.email = ["j.phenow@gmail.com"]
11
+ spec.description = %q{Light Queue wrapper tool}
12
+ spec.summary = %q{Light Queue wrapper tool}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ spec.add_development_dependency "simplecov"
25
+ spec.add_development_dependency "iron_mq"
26
+ spec.add_development_dependency "typhoeus"
27
+ spec.add_development_dependency "json", "~> 1.7.7"
28
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+ module Queuel
3
+ describe Client do
4
+ subject { described_class.new IronMq::Engine, {} }
5
+
6
+ it { should respond_to :push }
7
+ it { should respond_to :pop }
8
+ it { should respond_to :receive }
9
+ it { should respond_to :with }
10
+
11
+ describe "queue swapping" do
12
+ before do
13
+ Queuel.stub default_queue: "default"
14
+ end
15
+
16
+ it "can swap queues easily" do
17
+ subject.queue.should == "default"
18
+ subject.with(:new_queue).queue.should == "new_queue"
19
+ subject.queue.should == "default"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+ module Queuel
3
+ module IronMq
4
+ describe Engine do
5
+ it_should_behave_like "an engine"
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+ module Queuel
3
+ module IronMq
4
+ describe Message do
5
+ it_should_behave_like "a message"
6
+ describe "initialization with Iron Object" do
7
+ let(:queue_double) { double "Queue" }
8
+ let(:message_object) { double "IronMessage", id: 1, msg: "body", queue: queue_double }
9
+ subject { described_class.new_from_iron_mq_object(message_object) }
10
+
11
+ its(:id) { should == 1 }
12
+ its(:body) { should == "body" }
13
+ its(:queue) { should == queue_double }
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+ module Queuel
3
+ module IronMq
4
+ describe Poller do
5
+ it_should_behave_like "a poller"
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+ module Queuel
3
+ module IronMq
4
+ describe Queue do
5
+ let(:queue_object_with_message) { double "QueueObject", get: message }
6
+ let(:queue_object_with_nil_message) { double "QueueObject", get: nil }
7
+ it_should_behave_like "a queue"
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+ module Queuel
3
+ module Null
4
+ describe Engine do
5
+ it_should_behave_like "an engine"
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+ module Queuel
3
+ module Null
4
+ describe Message do
5
+ let(:null) { true }
6
+ it_should_behave_like "a message"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+ module Queuel
3
+ module Null
4
+ describe Poller do
5
+ let(:null) { true }
6
+ it_should_behave_like "a poller"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+ module Queuel
3
+ module Null
4
+ describe Queue do
5
+ let(:null) { true }
6
+ it_should_behave_like "a queue"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+ describe Queuel do
3
+ it { should respond_to :engine }
4
+ it { should respond_to :configure }
5
+ it { should respond_to :config }
6
+
7
+ it { should respond_to :push }
8
+ it { should respond_to :pop }
9
+ it { should respond_to :<< }
10
+ it { should respond_to :receive }
11
+
12
+ describe "configuration" do
13
+ before do
14
+ subject.configure do
15
+ credentials username: "jon"
16
+ end
17
+ end
18
+
19
+ it "set the credentials" do
20
+ subject.config.credentials.should == { username: "jon" }
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,24 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ require 'simplecov'
8
+ SimpleCov.start do
9
+ add_filter '/spec/'
10
+ end
11
+
12
+ require 'queuel'
13
+ Dir["./spec/support/**/*.rb"].sort.each {|f| require f}
14
+ RSpec.configure do |config|
15
+ config.treat_symbols_as_metadata_keys_with_true_values = true
16
+ config.run_all_when_everything_filtered = true
17
+ config.filter_run :focus
18
+
19
+ # Run specs in random order to surface order dependencies. If you find an
20
+ # order dependency and want to debug it, you can fix the order by providing
21
+ # the seed, which is printed after each run.
22
+ # --seed 1234
23
+ config.order = 'random'
24
+ end
@@ -0,0 +1,15 @@
1
+ shared_examples "an engine" do
2
+ let(:client_object) { double "Client Object" }
3
+ let(:client) { double "#{described_class.name} Client", new: client_object }
4
+ let(:queue_const) { Object.module_eval("#{described_class.to_s.split("::")[0..-2].join("::")}::Queue",__FILE__,__LINE__) }
5
+
6
+ before do
7
+ subject.stub client_proper: client
8
+ end
9
+
10
+ it { should respond_to :queue }
11
+
12
+ it "can grab a queue" do
13
+ subject.queue("some_queue").should be_a queue_const
14
+ end
15
+ end
@@ -0,0 +1,20 @@
1
+ shared_examples "a message" do
2
+ let(:id) { 1 }
3
+ let(:body) { "test" }
4
+ let(:queue) { nil }
5
+ subject { described_class.new id, body, queue }
6
+
7
+ it { should respond_to :id }
8
+ it { should respond_to :body }
9
+ it { should respond_to :queue }
10
+
11
+ its(:queue) { should be_nil }
12
+ its(:id) { should == 1 }
13
+ its(:body) { should == 'test' }
14
+
15
+ describe "with a given queue" do
16
+ let(:queue) { double "Queue object" }
17
+
18
+ its(:queue) { should == queue }
19
+ end
20
+ end