rock-queue-smpp 0.1.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.
data/LICENSE ADDED
File without changes
data/Rakefile ADDED
@@ -0,0 +1,59 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+ require 'rubygems/specification'
4
+ require 'spec/rake/spectask'
5
+ require 'date'
6
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/lib'
7
+ require 'rock-queue/tasks'
8
+
9
+ GEM = "rock-queue"
10
+ GEM_VERSION = "0.1.5"
11
+ AUTHOR = "Grzegorz Kazulak"
12
+ EMAIL = "gregorz.kazulak@gmail.com"
13
+ HOMEPAGE = "http://github.com/grzegorzkazulak/rock-queue"
14
+ SUMMARY = "A unified interface for various messaging queues"
15
+
16
+ spec = Gem::Specification.new do |s|
17
+ s.name = GEM
18
+ s.version = GEM_VERSION
19
+ s.platform = Gem::Platform::RUBY
20
+ s.has_rdoc = true
21
+ s.extra_rdoc_files = ["LICENSE"]
22
+ s.summary = SUMMARY
23
+ s.description = s.summary
24
+ s.author = AUTHOR
25
+ s.email = EMAIL
26
+ s.homepage = HOMEPAGE
27
+
28
+ s.require_path = 'lib'
29
+ s.autorequire = GEM
30
+ s.files = %w(LICENSE Rakefile) + Dir.glob("{lib,specs}/**/*")
31
+ end
32
+
33
+ Rake::GemPackageTask.new(spec) do |pkg|
34
+ pkg.gem_spec = spec
35
+ end
36
+
37
+ desc "install the gem locally"
38
+ task :install => [:package] do
39
+ sh %{sudo gem install pkg/#{GEM}-#{GEM_VERSION}}
40
+ end
41
+
42
+ desc "create a gemspec file"
43
+ task :make_spec do
44
+ File.open("#{GEM}.gemspec", "w") do |file|
45
+ file.puts spec.to_ruby
46
+ end
47
+ end
48
+
49
+ desc "Run all examples (or a specific spec with TASK=spec/some_file.rb)"
50
+ Spec::Rake::SpecTask.new('spec') do |t|
51
+ t.spec_opts = ["-cfs"]
52
+ t.spec_files = begin
53
+ if ENV["TASK"]
54
+ ENV["TASK"].split(',').map { |task| "spec/**/#{task}_spec.rb" }
55
+ else
56
+ FileList['spec/**/*_spec.rb']
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,28 @@
1
+ require 'active_record'
2
+
3
+ module RockQueue
4
+ module ActiveRecordHelper
5
+ def self.included(base)
6
+ base.extend ClassMethods
7
+ base.send(:include, InstanceMethods)
8
+ end
9
+
10
+ module ClassMethods
11
+ def perform(*args)
12
+ args = args.first
13
+ id = args.shift
14
+ method = args.shift
15
+ find(id).send(method, *args)
16
+ end
17
+ end
18
+
19
+ module InstanceMethods
20
+ def async(method, *args)
21
+ config = RockQueue::Config.settings
22
+ rq = RockQueue::Base.new config.adapter, {:server => config.host, :port => config.port}
23
+ rq.push self.class, id, method, *args
24
+ end
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,21 @@
1
+ begin
2
+ require "beanstalk-client"
3
+ rescue
4
+ puts "You need `beanstalk-client` gem to use the Beanstalkd rock-queue interface"
5
+ exit
6
+ end
7
+
8
+ module RockQueue
9
+ class Beanstalkd
10
+
11
+ attr_reader :obj
12
+
13
+ def initialize(options = {})
14
+ @obj = Beanstalk::Pool.new(["#{options[:server]}:#{options[:port]}"])
15
+ end
16
+
17
+ def pop
18
+ loop
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,24 @@
1
+ begin
2
+ require "delayed_job"
3
+ rescue
4
+ puts "You need `delayed_job` gem to use the Delayed Job rock-queue interface"
5
+ exit
6
+ end
7
+
8
+ module RockQueue
9
+ class DelayedJob
10
+
11
+ attr_reader :obj
12
+
13
+ def initialize(options = {})
14
+ end
15
+
16
+ def push(value, options)
17
+ Delayed::Job.enqueue value
18
+ end
19
+
20
+ def pop
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,35 @@
1
+ begin
2
+ require 'resque'
3
+ rescue
4
+ puts "You need `resque` gem to use the Resque rock-queue interface"
5
+ exit
6
+ end
7
+
8
+ module RockQueue
9
+ class ResqueQueue
10
+
11
+ attr_reader :obj
12
+
13
+ # Contructor of Resque adapter
14
+ def initialize(options)
15
+ Resque.redis = "#{options[:server]}:#{options[:port]}"
16
+ end
17
+
18
+ # Push item from Resque queue
19
+ def push(value, args)
20
+ if !defined?(value.queue)
21
+ value.class_eval do
22
+ @queue = :default
23
+ end
24
+ end
25
+ Resque.enqueue value, args
26
+ end
27
+
28
+ # Retrieve item from Resque queue
29
+ def pop
30
+ job = Resque.reserve :default
31
+ [job.payload_class, job.args] if job
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,30 @@
1
+ module RockQueue
2
+ class Config
3
+
4
+ attr_accessor :adapter, :host, :port, :smpp_settings
5
+
6
+ # Return the instance
7
+ def self.instance
8
+ @__instance__ ||= new
9
+ end
10
+
11
+ # Yields a singleton instance of RockQueue::Config so you can specify config
12
+ # information like server address, port etc.
13
+ def self.settings
14
+ if block_given?
15
+ yield self.instance
16
+ else
17
+ self.instance
18
+ end
19
+ end
20
+
21
+ def notifiers
22
+ if block_given?
23
+ yield Notifiers.instance
24
+ else
25
+ Notifiers.instance
26
+ end
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,5 @@
1
+ module RockQueue
2
+ class AdapterNotSupported < RuntimeError; end
3
+ class NoClassError < RuntimeError; end
4
+ class QueueingServerNotRunning < RuntimeError; end
5
+ end
@@ -0,0 +1,2 @@
1
+ # AbstractNotifier is a base class (interface) for all your notifiers.
2
+ class AbstractNotifier; end
@@ -0,0 +1,39 @@
1
+ module RockQueue
2
+
3
+ class EmailNotifier < AbstractNotifier
4
+
5
+ def initialize(config)
6
+ $server_config = config
7
+ end
8
+
9
+ # Notify by email
10
+ def update(error)
11
+
12
+ begin
13
+ require 'mail'
14
+ rescue
15
+ puts "You need `mail` gem to use the Email Notifier"
16
+ end
17
+
18
+ puts "Sending e-mail message: #{error.message}"
19
+
20
+ Mail.defaults do
21
+ smtp do
22
+ host $server_config[:server]
23
+ port $server_config[:port]
24
+ user $server_config[:username]
25
+ pass $server_config[:password]
26
+ end
27
+ end
28
+
29
+ Mail.deliver do
30
+ from $server_config[:from]
31
+ to $server_config[:to]
32
+ subject "Processing error - '#{error.message}''"
33
+ body error.backtrace.join("\n")
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,23 @@
1
+ require "observer"
2
+
3
+ module RockQueue
4
+ class Notifiers
5
+ include Observable
6
+
7
+ # Return the instance of notifiers registry.
8
+ def self.instance
9
+ @__instance__ ||= new
10
+ end
11
+
12
+ # Registers the observer. You have to pass the instance of your notifier.
13
+ def register(instance)
14
+ add_observer instance
15
+ end
16
+
17
+ # Notifies all the observers
18
+ def notify(message)
19
+ changed
20
+ notify_observers message
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,34 @@
1
+ module RockQueue
2
+
3
+ # Queue object wrapper
4
+ class QueueObject
5
+
6
+ DEFAULT_FAIL_LIMIT = 3
7
+
8
+ attr_reader :object, :args, :fails
9
+
10
+ # Constructor of queue objects wrapper
11
+ def initialize(object, args)
12
+ @object = object
13
+ @args = args
14
+ @fails = Array.new
15
+ end
16
+
17
+ # Add processing fail
18
+ def add_fail(exception)
19
+ @fails << exception
20
+ if @fails.length < DEFAULT_FAIL_LIMIT
21
+ return true
22
+ else
23
+ RockQueue::Notifiers.instance.notify(exception)
24
+ end
25
+ end
26
+
27
+ # Get sleep time after fail
28
+ def get_sleep_time
29
+ 2 ** @fails.length
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -0,0 +1,11 @@
1
+ require 'rock-queue'
2
+
3
+ namespace :rock_queue do
4
+ desc "Start a Rock Queue worker"
5
+ task :work do
6
+ worker = RockQueue::Worker.new
7
+ worker.verbose = ENV['VERBOSE']
8
+ puts "=> Rock-queue worker initialized (#{worker})"
9
+ worker.work
10
+ end
11
+ end
@@ -0,0 +1 @@
1
+ RockQueue Web Interface
@@ -0,0 +1,25 @@
1
+ require 'rubygems'
2
+ require 'sinatra/base'
3
+ require 'erb'
4
+
5
+ module RockQueue
6
+ class Web < Sinatra::Base
7
+
8
+ configure do
9
+ current_dir = File.dirname(File.expand_path(__FILE__))
10
+ set :views, "#{current_dir}/web/views"
11
+ set :public, "#{current_dir}/web/public"
12
+ set :static, true
13
+ set :raise_errors, true
14
+ end
15
+
16
+ get '/' do
17
+ redirect '/dashboard'
18
+ end
19
+
20
+ get '/dashboard' do
21
+ erb :dashboard
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,52 @@
1
+ module RockQueue
2
+ class Worker
3
+ # Whether the worker should log basic info to STDOUT
4
+ attr_accessor :verbose
5
+
6
+ # Initialize connection to queue server
7
+ def initialize
8
+ puts "=> Initializing..."
9
+ config = RockQueue::Config.settings
10
+ @queue = RockQueue::Base.new config.adapter, {
11
+ :server => config.host,
12
+ :port => config.port
13
+ }
14
+ end
15
+
16
+ # Main worker loop where all jobs are beeing pulled of the queue.
17
+ # This is also a place where every job starts and ends it's lifecycle.
18
+ def work
19
+ config = RockQueue::Config.settings
20
+ puts "=> Worker ready. Hold your horses!"
21
+ loop do
22
+ EventMachine::run do
23
+ @@tx = EventMachine::connect(
24
+ config.smpp_config[:host],
25
+ config.smpp_config[:port],
26
+ Smpp::Transceiver,
27
+ config.smpp_config,
28
+ self # delegate that will receive callbacks on MOs and DRs and other events
29
+ )
30
+ $stdout.flush
31
+ @queue.receive do |queue|
32
+ if queue
33
+ # code that actually performs the action
34
+ begin
35
+ args = queue.args.first
36
+ args.empty? ? queue.object.perform : queue.object.perform(args)
37
+ rescue Object => e
38
+ # Add failed processing and retry
39
+ if queue.add_fail(e)
40
+ sleep(queue.get_sleep_time)
41
+ puts "=> Processing fail! Retrying #{queue.fails.length}"
42
+ retry
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ end
52
+ end
data/lib/rock-queue.rb ADDED
@@ -0,0 +1,77 @@
1
+ $:.unshift File.expand_path(File.dirname(__FILE__))
2
+ require 'logger'
3
+
4
+ module RockQueue
5
+
6
+ autoload :Config, 'rock-queue/config'
7
+
8
+ autoload :AbstractNotifier, 'rock-queue/notifiers/abstract_notifier'
9
+ autoload :Notifiers, 'rock-queue/notifiers'
10
+ autoload :EmailNotifier, 'rock-queue/notifiers/email_notifier'
11
+
12
+ autoload :Worker, 'rock-queue/worker'
13
+ autoload :QueueObject, 'rock-queue/queue_object'
14
+
15
+ # Adapters
16
+ autoload :Beanstalkd, 'rock-queue/adapters/beanstalkd'
17
+ autoload :ResqueQueue, 'rock-queue/adapters/resque'
18
+ autoload :DelayedJob, 'rock-queue/adapters/delayed_job'
19
+
20
+ autoload :AdapterNotSupported, 'rock-queue/errors'
21
+ autoload :NoClassError, 'rock-queue/errors'
22
+ autoload :QueueingServerNotRunning, 'rock-queue/errors'
23
+ autoload :ActiveRecordHelper, 'rock-queue/active_record_helper'
24
+
25
+ attr_reader :adapter
26
+
27
+ class Base
28
+
29
+ # Initializes the whole thing and makes the connection to the
30
+ # queueing server using selected adapter (passed as lowercased symbol)
31
+ def initialize(adapter, *options)
32
+ # Any better way to do this? :-)
33
+ options = options.first
34
+ if options.include?(:server) && options.include?(:port)
35
+ case adapter
36
+ when :beanstalkd
37
+ @adapter = Beanstalkd.new(options)
38
+ when :resque
39
+ @adapter = ResqueQueue.new(options)
40
+ when :delayed_job
41
+ @adapter = DelayedJob.new(options)
42
+ end
43
+ else
44
+ raise ArgumentError
45
+ end
46
+ end
47
+
48
+
49
+ # Pushes the value (in our case it should always be an object)
50
+ # onto the queue using previously selected adapter
51
+ def push(value, *args)
52
+ @adapter.push(value, args)
53
+ end
54
+
55
+
56
+ # Pulls the data off the queue. There are two ways to do so:
57
+ # - Call receive with no block (gets you a single item)
58
+ # - Pass a block to it (creates and endles loop that constantly pulls items from the queue as they become available)
59
+ # All calls to the queueing server are made through the previosuly selected adaper.
60
+ def receive
61
+ if block_given?
62
+ obj, args = @adapter.pop
63
+ if obj
64
+ yield QueueObject.new(obj, args)
65
+ end
66
+ else
67
+ raise 'No block given'
68
+ end
69
+ end
70
+
71
+
72
+ def method_missing(sym, *args, &block)
73
+ @adapter.send sym, *args, &block
74
+ end
75
+
76
+ end
77
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rock-queue-smpp
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Grzegorz Kazulak, Matt Van Veenendaal
8
+ autorequire: rock-queue
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-11-17 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Fork of Rock-Queue to run an SMPP Gateway
17
+ email: m@mattvv.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ files:
25
+ - LICENSE
26
+ - Rakefile
27
+ - lib/rock-queue/active_record_helper.rb
28
+ - lib/rock-queue/adapters/beanstalkd.rb
29
+ - lib/rock-queue/adapters/delayed_job.rb
30
+ - lib/rock-queue/adapters/resque.rb
31
+ - lib/rock-queue/config.rb
32
+ - lib/rock-queue/errors.rb
33
+ - lib/rock-queue/notifiers/abstract_notifier.rb
34
+ - lib/rock-queue/notifiers/email_notifier.rb
35
+ - lib/rock-queue/notifiers.rb
36
+ - lib/rock-queue/queue_object.rb
37
+ - lib/rock-queue/tasks.rb
38
+ - lib/rock-queue/web/views/dashboard.erb
39
+ - lib/rock-queue/web.rb
40
+ - lib/rock-queue/worker.rb
41
+ - lib/rock-queue.rb
42
+ has_rdoc: true
43
+ homepage: http://github.com/mattvv/rock-queue-rmpp
44
+ licenses: []
45
+
46
+ post_install_message:
47
+ rdoc_options: []
48
+
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ version:
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ requirements: []
64
+
65
+ rubyforge_project:
66
+ rubygems_version: 1.3.5
67
+ signing_key:
68
+ specification_version: 3
69
+ summary: Fork of Rock-Queue to run an SMPP Gateway
70
+ test_files: []
71
+