queueing_proxy 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.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'ext/gem_rake'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
4
+
5
+ require 'queueing_proxy'
6
+
7
+ QueueingProxy::CLI.start
8
+
data/ext/gem_rake.rb ADDED
@@ -0,0 +1,126 @@
1
+ module Bundler
2
+ class GemHelper
3
+
4
+ def self.install_tasks
5
+ dir = caller.find{|c| /Rakefile:/}[/^(.*?)\/Rakefile:/, 1]
6
+ GemHelper.new(dir).install
7
+ end
8
+
9
+ attr_reader :spec_path, :base, :name
10
+
11
+ def initialize(base, name = nil)
12
+ @base = base
13
+ @name = name || interpolate_name
14
+ @spec_path = File.join(@base, "#{@name}.gemspec")
15
+ end
16
+
17
+ def install
18
+ desc 'Build your gem into the pkg directory'
19
+ task 'build' do
20
+ build_gem
21
+ end
22
+
23
+ desc 'Install your gem into the pkg directory'
24
+ task 'install' do
25
+ install_gem
26
+ end
27
+
28
+ desc 'Push your gem to rubygems'
29
+ task 'push' do
30
+ push_gem
31
+ end
32
+ end
33
+
34
+ def build_gem
35
+ file_name = nil
36
+ sh("gem build #{spec_path}") {
37
+ file_name = File.basename(built_gem_path)
38
+ FileUtils.mkdir_p(File.join(base, 'pkg'))
39
+ FileUtils.mv(built_gem_path, 'pkg')
40
+ }
41
+ File.join(base, 'pkg', file_name)
42
+ end
43
+
44
+ def install_gem
45
+ built_gem_path = build_gem
46
+ sh("gem install #{built_gem_path}")
47
+ end
48
+
49
+ def push_gem
50
+ guard_clean
51
+ guard_already_tagged
52
+ tag_version {
53
+ git_push
54
+ rubygem_push(build_gem)
55
+ }
56
+ end
57
+
58
+ protected
59
+ def rubygem_push(path)
60
+ sh("gem push #{path}")
61
+ end
62
+
63
+ def built_gem_path
64
+ Dir[File.join(base, "#{name}-*.gem")].sort_by{|f| File.mtime(f)}.last
65
+ end
66
+
67
+ def interpolate_name
68
+ gemspecs = Dir[File.join(base, "*.gemspec")]
69
+ raise "Unable to determine name from existing gemspec." unless gemspecs.size == 1
70
+
71
+ File.basename(gemspecs.first)[/^(.*)\.gemspec$/, 1]
72
+ end
73
+
74
+ def git_push
75
+ sh "git push --all"
76
+ sh "git push --tags"
77
+ end
78
+
79
+ def guard_already_tagged
80
+ sh('git tag').split(/\n/).include?(current_version_tag) and raise("This tag has already been committed to the repo.")
81
+ end
82
+
83
+ def guard_clean
84
+ clean? or raise("There are files that need to be committed first.")
85
+ end
86
+
87
+ def clean?
88
+ sh("git ls-files -dm").split("\n").size.zero?
89
+ end
90
+
91
+ def tag_version
92
+ sh "git tag #{current_version_tag}"
93
+ yield if block_given?
94
+ rescue
95
+ sh "git tag -d #{current_version_tag}"
96
+ raise
97
+ end
98
+
99
+ def current_version
100
+ raise("Version file could not be found at #{version_file_path}") unless File.exist?(version_file_path)
101
+ File.read(version_file_path)[/V(ERSION|ersion)\s*=\s*(["'])(.*?)\2/, 3]
102
+ end
103
+
104
+ def version_file_path
105
+ File.join(base, 'lib', name, 'version.rb')
106
+ end
107
+
108
+ def current_version_tag
109
+ "v#{current_version}"
110
+ end
111
+
112
+ def sh(cmd, &block)
113
+ output, code = sh_with_code(cmd, &block)
114
+ code == 0 ? output : raise(output)
115
+ end
116
+
117
+ def sh_with_code(cmd, &block)
118
+ output = ''
119
+ Dir.chdir(base) {
120
+ output = `#{cmd}`
121
+ block.call if block and $? == 0
122
+ }
123
+ [output, $?]
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,17 @@
1
+ require 'thor'
2
+
3
+ module QueueingProxy
4
+ class CLI < Thor
5
+
6
+ def initialize
7
+ super
8
+ end
9
+
10
+ default_task :start
11
+
12
+ desc "start", "Start a proxy"
13
+ def start(config = '/etc/queueing_proxy.yml')
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,56 @@
1
+ module QueueingProxy
2
+ class Dispatcher
3
+ attr_reader :logger
4
+
5
+ def initialize(logger, to_host, to_port, beanstalk_host, tube)
6
+ @logger, @to_host, @to_port, @beanstalk_host, @tube = logger, to_host, to_port, beanstalk_host, tube
7
+ @beanstalk = EMJack::Connection.new(:host => @beanstalk_host, :tube => @tube)
8
+ @beanstalk.watch(@tube)
9
+ logger.info "Starting dispatcher on #{to_host}:#{to_port} using beanstalk at #{tube}@#{beanstalk_host}"
10
+ end
11
+
12
+ def run
13
+ @beanstalk.reserve do |job|
14
+ logger.info "Dispatching #{job.jobid}"
15
+ parsed_job = JSON.parse(job.body)
16
+ begin
17
+ EventMachine.connect(@to_host, @to_port, DispatchClient) { |c|
18
+ c.payload = parsed_job['data']
19
+ c.dispatcher = self
20
+ c.logger = logger
21
+ c.job = job
22
+ c.dispatcher = self
23
+ }
24
+ rescue EventMachine::ConnectionError
25
+ job.release(:delay => 5)
26
+ logger.info("Problem connecting")
27
+ EM.add_timer(5){ run }
28
+ end
29
+ end
30
+ end
31
+
32
+ class DispatchClient < EventMachine::Connection
33
+ attr_accessor :payload, :dispatcher, :logger, :dispatcher, :job
34
+
35
+ def connection_completed
36
+ send_data(payload)
37
+ end
38
+
39
+ def receive_data(data)
40
+ status = Integer(data[/^HTTP\/(1\.1|1\.0) (\d+)/, 2])
41
+ close_connection
42
+ if status == 200
43
+ logger.info "Done dispatching #{job.jobid}"
44
+ job.delete
45
+ else
46
+ logger.info "Error #{status}"
47
+ job.release(:delay => 5)
48
+ end
49
+ end
50
+
51
+ def unbind
52
+ dispatcher.run
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,48 @@
1
+ require 'logger'
2
+
3
+ module QueueingProxy
4
+ class DSL
5
+ def initialize(&block)
6
+ @dispatcher_count = 1
7
+ @logger = Logger.new(STDOUT)
8
+ instance_eval(&block) if block
9
+ end
10
+
11
+ def to(host, port)
12
+ @to_host = host
13
+ @to_port = port
14
+ self
15
+ end
16
+
17
+ def from(host, port)
18
+ @from_host = host
19
+ @from_port = port
20
+ self
21
+ end
22
+
23
+ def times(count)
24
+ @dispatcher_count = count
25
+ self
26
+ end
27
+
28
+ def queue_with(beanstalk_host, tube)
29
+ @beanstalk_host = beanstalk_host
30
+ @tube = tube
31
+ self
32
+ end
33
+
34
+ def logger(logger)
35
+ @logger = logger
36
+ self
37
+ end
38
+
39
+ def run
40
+ unless EM.reactor_running?
41
+ EM.run{ run }
42
+ else
43
+ Queuer.new(@logger, @from_host, @from_port, @beanstalk_host, @tube).run
44
+ @dispatcher_count.times { Dispatcher.new(@logger, @to_host, @to_port, @beanstalk_host, @tube).run }
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,57 @@
1
+ module QueueingProxy
2
+ class Queuer
3
+ attr_reader :logger
4
+
5
+ def initialize(logger, host, port, beanstalk_host, tube)
6
+ @logger, @host, @port, @beanstalk_host, @tube = logger, host, port, beanstalk_host, tube
7
+ logger.info "Starting queuer on #{host}:#{port} using beanstalk at #{tube}@#{beanstalk_host}"
8
+ end
9
+
10
+ def run
11
+ beanstalk = EMJack::Connection.new(:host => @beanstalk_host, :tube => @tube)
12
+ app = proc do |env|
13
+ logger.info "Queueing #{env['HTTP_VERSION']} #{env['PATH_INFO']} #{env['REQUEST_METHOD']}"
14
+ [200, {}, []]
15
+ end
16
+ backend = FakeBackend.new
17
+ EM.start_server(@host, @port, QueuerConnection) do |conn|
18
+ conn.beanstalk = beanstalk
19
+ conn.app = app
20
+ conn.backend = backend
21
+ conn.logger = logger
22
+ end
23
+ end
24
+
25
+ class FakeBackend
26
+ def connection_finished(conn)
27
+ end
28
+ end
29
+
30
+ class QueuerConnection < Thin::Connection
31
+ attr_accessor :beanstalk, :logger
32
+
33
+ def post_init
34
+ @data = ''
35
+ super
36
+ end
37
+
38
+ def receive_data(data)
39
+ @data << data
40
+ super(data)
41
+ end
42
+
43
+ def unbind
44
+ queue_data
45
+ super
46
+ end
47
+
48
+ def queue_data
49
+ if @data != ''
50
+ beanstalk.put({:data => @data, :time => Time.new.to_i}.to_json) { |id|
51
+ logger.info "Job queued #{id}"
52
+ }
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,3 @@
1
+ module QueueingProxy
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,22 @@
1
+ require 'thin'
2
+ require 'eventmachine'
3
+ require 'em-jack'
4
+ require 'json'
5
+
6
+ require 'queueing_proxy/cli'
7
+ require 'queueing_proxy/dsl'
8
+ require 'queueing_proxy/queuer'
9
+ require 'queueing_proxy/version'
10
+ require 'queueing_proxy/dispatcher'
11
+
12
+ module QueueingProxy
13
+
14
+ def self.from(host, port)
15
+ DSL.new.from(host, port)
16
+ end
17
+
18
+ end
19
+
20
+ def QueueingProxy(&blk)
21
+ QueueingProxy::DSL.new(&blk)
22
+ end
@@ -0,0 +1,39 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require File.join(File.dirname(__FILE__), 'lib', 'queueing_proxy', 'version')
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'queueing_proxy'
7
+ s.version = QueueingProxy::VERSION
8
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
9
+ s.authors = ["Joshua Hull"]
10
+ s.date = '2010-07-21'
11
+ s.summary = "Queueing proxy backed by EM/Beanstalk for a very weird purpose."
12
+ s.description = "Queueing proxy backed by EM/Beanstalk for a very weird purpose."
13
+ s.email = %q{joshbuddy@gmail.com}
14
+ s.extra_rdoc_files = []
15
+ s.files = `git ls-files`.split("\n")
16
+ s.homepage = %q{http://github.com/joshbuddy/queueing_proxy}
17
+ s.rdoc_options = ["--charset=UTF-8"]
18
+ s.require_paths = ["lib"]
19
+ s.rubygems_version = %q{1.3.7}
20
+ s.test_files = `git ls-files`.split("\n").select{|f| f =~ /^spec/}
21
+ s.rubyforge_project = 'queueing_proxy'
22
+
23
+ # dependencies
24
+ s.add_runtime_dependency 'eventmachine'
25
+ s.add_runtime_dependency 'em-jack'
26
+ s.add_runtime_dependency 'thin'
27
+ s.add_runtime_dependency 'json'
28
+
29
+ if s.respond_to? :specification_version then
30
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
31
+ s.specification_version = 3
32
+
33
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
34
+ else
35
+ end
36
+ else
37
+ end
38
+ end
39
+
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: queueing_proxy
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Joshua Hull
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-07-21 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: eventmachine
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: em-jack
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: thin
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :runtime
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: json
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ type: :runtime
76
+ version_requirements: *id004
77
+ description: Queueing proxy backed by EM/Beanstalk for a very weird purpose.
78
+ email: joshbuddy@gmail.com
79
+ executables: []
80
+
81
+ extensions: []
82
+
83
+ extra_rdoc_files: []
84
+
85
+ files:
86
+ - Gemfile
87
+ - Rakefile
88
+ - bin/queueing_proxy
89
+ - ext/gem_rake.rb
90
+ - lib/queueing_proxy.rb
91
+ - lib/queueing_proxy/cli.rb
92
+ - lib/queueing_proxy/dispatcher.rb
93
+ - lib/queueing_proxy/dsl.rb
94
+ - lib/queueing_proxy/queuer.rb
95
+ - lib/queueing_proxy/version.rb
96
+ - queueing_proxy.gemspec
97
+ has_rdoc: true
98
+ homepage: http://github.com/joshbuddy/queueing_proxy
99
+ licenses: []
100
+
101
+ post_install_message:
102
+ rdoc_options:
103
+ - --charset=UTF-8
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ hash: 3
112
+ segments:
113
+ - 0
114
+ version: "0"
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ hash: 3
121
+ segments:
122
+ - 0
123
+ version: "0"
124
+ requirements: []
125
+
126
+ rubyforge_project: queueing_proxy
127
+ rubygems_version: 1.3.7
128
+ signing_key:
129
+ specification_version: 3
130
+ summary: Queueing proxy backed by EM/Beanstalk for a very weird purpose.
131
+ test_files: []
132
+