trinidad_sidekiq_extension 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,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.swp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in trinidad_sidekiq_extension.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Adrian Madrid
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,51 @@
1
+ # Trinidad Sidekiq Extension
2
+
3
+ Run Sidekiq workers within the Trinidad process.
4
+
5
+ Inspiration: https://github.com/carlhoerberg/trinidad_threaded_resque_extension
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'trinidad_sidekiq_extension', require: false
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Then configure it via config/trinidad.rb:
18
+
19
+ ```ruby
20
+ require 'bundler/setup'
21
+ Trinidad.configure do |config|
22
+ config.jruby_min_runtimes = 1
23
+ config.jruby_max_runtimes = 1
24
+ ...
25
+ config.web_apps = {
26
+ default = {
27
+ rackup: 'config.ru'
28
+ extensions = {
29
+ sidekiq: {
30
+ arguments: '-c 10 -r ./config/sidekiq'
31
+ }
32
+ }
33
+ }
34
+ }
35
+ end
36
+ ```
37
+
38
+ ## Usage
39
+
40
+ Start trinidad and enjoy the low memory usage while having high concurrency.
41
+
42
+ Note that becasue JRuby can't fork you want to have well behaved workers, watch out for memory leakage. Naturally your workers have to be thread safe.
43
+
44
+ ## Contributing
45
+
46
+ 1. Fork it
47
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
48
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
49
+ 4. Push to the branch (`git push origin my-new-feature`)
50
+ 5. Create new Pull Request
51
+
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,15 @@
1
+ require 'trinidad'
2
+ require_relative "trinidad_sidekiq_extension/version"
3
+ require_relative "trinidad_sidekiq_extension/background_manager"
4
+ require_relative "trinidad_sidekiq_extension/lifecycle_listener"
5
+
6
+ module Trinidad
7
+ module Extensions
8
+ class SidekiqWebAppExtension < WebAppExtension
9
+ def configure(app_context)
10
+ app_context.add_lifecycle_listener Sidekiq::LifecycleListener.new(@options)
11
+ end
12
+ end
13
+ end
14
+ end
15
+
@@ -0,0 +1,152 @@
1
+ $stdout.sync = true
2
+
3
+ require 'yaml'
4
+ require 'singleton'
5
+ require 'optparse'
6
+ require 'celluloid'
7
+ require 'erb'
8
+
9
+ require 'sidekiq'
10
+ require 'sidekiq/util'
11
+ require 'sidekiq/manager'
12
+ require 'sidekiq/scheduled'
13
+
14
+ module Sidekiq
15
+ class BackgroundManager
16
+ include Util
17
+ include Singleton
18
+
19
+ # Used for BM testing
20
+ attr_accessor :code
21
+ attr_accessor :manager
22
+ attr_reader :interrupted
23
+
24
+ def initialize
25
+ @code = nil
26
+ @interrupt_mutex = Mutex.new
27
+ @interrupted = false
28
+ end
29
+
30
+ def configure(given_options = { })
31
+ @code = nil
32
+ Sidekiq.logger
33
+
34
+ logger.debug "BM configure : options : #{options.inspect}" if options[:verbose]
35
+ logger.debug "BM configure : given_options : #{given_options.inspect}" if options[:verbose]
36
+ config_options = parse_config given_options
37
+ logger.debug "BM configure : config_options : #{config_options.inspect}" if options[:verbose]
38
+ options.merge! config_options
39
+ logger.debug "BM configure : options : #{options.inspect}" if options[:verbose]
40
+
41
+ Sidekiq.logger.level = Logger::DEBUG if options[:verbose]
42
+ Celluloid.logger = nil unless options[:verbose]
43
+
44
+ validate!
45
+ boot_system
46
+ end
47
+
48
+ def run
49
+ logger.debug "Booting Sidekiq BM #{Sidekiq::VERSION} with Redis at #{redis { |x| x.client.id }}"
50
+ logger.debug "Running in #{RUBY_DESCRIPTION}"
51
+ logger.debug "Dir.pwd : #{Dir.pwd}"
52
+ logger.debug Sidekiq::LICENSE
53
+
54
+ @manager = Sidekiq::Manager.new(options)
55
+ poller = Sidekiq::Scheduled::Poller.new
56
+ begin
57
+ logger.debug 'BM Starting processing ...'
58
+ @manager.start!
59
+ poller.poll!(true)
60
+ sleep
61
+ rescue Interrupt
62
+ logger.debug 'BM Shutting down ...'
63
+ poller.terminate! if poller.alive?
64
+ @manager.stop!(:shutdown => true, :timeout => options[:timeout])
65
+ @manager.wait(:shutdown)
66
+ # WILL NOT explicitly exit because Trinidad will take care of exiting
67
+ # in its own sweet time.
68
+ # exit(0)
69
+ end
70
+ end
71
+
72
+ def interrupt
73
+ @interrupt_mutex.synchronize do
74
+ unless @interrupted
75
+ logger.debug "BM interrupting ..."
76
+ @interrupted = true
77
+ Thread.main.raise Interrupt
78
+ end
79
+ end
80
+ end
81
+
82
+ private
83
+
84
+ def die(code)
85
+ exit(code)
86
+ end
87
+
88
+ def options
89
+ Sidekiq.options
90
+ end
91
+
92
+ def detected_environment
93
+ options[:environment] ||= ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
94
+ end
95
+
96
+ def boot_system
97
+ ENV['RACK_ENV'] = ENV['RAILS_ENV'] = detected_environment
98
+
99
+ raise ArgumentError, "#{options[:require]} does not exist" unless File.exist?(options[:require])
100
+
101
+ logger.debug "BM Booting system with require [#{options[:require]}] ..."
102
+ if File.directory?(options[:require])
103
+ logger.debug "BM require [#{options[:require]}] is a directory, loading Rails ..."
104
+ begin
105
+ require 'rails'
106
+ require 'sidekiq/rails'
107
+ logger.debug "BM requiring #{options[:require]} ..."
108
+ require File.expand_path("#{options[:require]}/config/environment.rb")
109
+ ::Rails.application.eager_load!
110
+ rescue LoadError => e
111
+ logger.debug "EXCEPTION: #{e.class.name} : #{e.message}"
112
+ logger.debug "We could not load rails, you will run into trouble!"
113
+ raise "BM Could not load rails for require [#{options[:require]}], exiting ..."
114
+ end
115
+ else
116
+ logger.debug "BM require [#{options[:require]}] is NOT a directory, requiring file ..."
117
+ require options[:require]
118
+ end
119
+ end
120
+
121
+ def validate!
122
+ options[:queues] << 'default' if options[:queues].empty?
123
+
124
+ if !File.exist?(options[:require]) ||
125
+ (File.directory?(options[:require]) && !File.exist?("#{options[:require]}/config/application.rb"))
126
+ logger.info "=================================================================="
127
+ logger.info " Please point sidekiq to a Rails 3 application or a Ruby file "
128
+ logger.info " to load your worker classes with options[:require]= [DIR|FILE]. "
129
+ logger.info "=================================================================="
130
+ logger.info "options : #{options.inspect}"
131
+ die(1)
132
+ end
133
+ end
134
+
135
+ def parse_config(given_options)
136
+ if given_options[:config_file] && File.exist?(given_options[:config_file])
137
+ opts = YAML.load(ERB.new(IO.read(given_options[:config_file])).result)
138
+ queues = opts.delete(:queues) || []
139
+ queues.each { |name, weight| parse_queues(opts, name, weight) }
140
+ given_options.update opts
141
+ end
142
+ given_options
143
+ end
144
+
145
+ def parse_queues(opts, q, weight)
146
+ [weight.to_i, 1].max.times do
147
+ (opts[:queues] ||= []) << q
148
+ end
149
+ end
150
+
151
+ end
152
+ end
@@ -0,0 +1,49 @@
1
+ module Trinidad
2
+ module Extensions
3
+ module Sidekiq
4
+ class LifecycleListener
5
+ include Trinidad::Tomcat::LifecycleListener
6
+ attr_accessor :options, :workers, :threads
7
+
8
+ def initialize(options = { })
9
+ @options = options || {}
10
+ end
11
+
12
+ def lifecycleEvent(event)
13
+ case event.type
14
+ when Trinidad::Tomcat::Lifecycle::AFTER_START_EVENT
15
+ STDOUT << "[Trinidad:Sidekiq] event [#{event.type}] << start >>\n" if options[:verbose]
16
+ start_cli
17
+ when Trinidad::Tomcat::Lifecycle::BEFORE_STOP_EVENT
18
+ STDOUT << "[Trinidad:Sidekiq] event [#{event.type}] << stop >>\n" if options[:verbose]
19
+ stop_cli
20
+ else
21
+ STDOUT << "[Trinidad:Sidekiq] event [#{event.type}] skipped\n" if options[:verbose]
22
+ end
23
+ end
24
+
25
+ def start_cli
26
+ STDOUT << "[Trinidad:Sidekiq] starting sidekiq bm with options [#{@options}]\n" if options[:verbose]
27
+ unless options[:require]
28
+ raise "You probably want to send a require option to the sidekiq background manager ..." if options[:verbose]
29
+ end
30
+
31
+ STDOUT << "[Trinidad:Sidekiq] getting it going ...\n"
32
+ bm = ::Sidekiq::BackgroundManager.instance
33
+ STDOUT << "[Trinidad:Sidekiq] got original bm (#{bm.class.name}) #{bm.inspect} ...\n" if options[:verbose]
34
+ bm.configure @options
35
+ STDOUT << "[Trinidad:Sidekiq] got modified bm (#{bm.class.name}) #{bm.inspect} ...\n" if options[:verbose]
36
+ res = bm.run
37
+ STDOUT << "[Trinidad:Sidekiq] got bm running (#{res.class.name}) #{res.inspect} ...\n" if options[:verbose]
38
+ end
39
+
40
+ def stop_cli
41
+ STDOUT << "[Trinidad:Sidekiq] Stopping sidekiq cli ...\n" if options[:verbose]
42
+ res = ::Sidekiq::BackgroundManager.instance.interrupt
43
+ STDOUT << "[Trinidad:Sidekiq] got bm stopped (#{res.class.name})#{res.inspect} ...\n" if options[:verbose]
44
+ end
45
+
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,3 @@
1
+ module TrinidadThreadedSidekiqExtension
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/trinidad_sidekiq_extension/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Adrian Madrid"]
6
+ gem.email = ["aemadrid@gmail.com"]
7
+ gem.description = %q{Runs Sidekiq workers within the Trinidad application server}
8
+ gem.summary = %q{Runs Sidekiq workers within the Trinidad application server}
9
+ gem.homepage = "https://github.com/aemadrid/trinidad_sidekiq_extension"
10
+
11
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
+ gem.files = `git ls-files`.split("\n")
13
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ gem.name = "trinidad_sidekiq_extension"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = TrinidadThreadedSidekiqExtension::VERSION
17
+
18
+ gem.add_development_dependency "rake"
19
+ gem.add_runtime_dependency "trinidad"
20
+ gem.add_runtime_dependency "sidekiq"
21
+ end
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: trinidad_sidekiq_extension
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Adrian Madrid
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-02 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ version_requirements: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ! '>='
19
+ - !ruby/object:Gem::Version
20
+ version: !binary |-
21
+ MA==
22
+ none: false
23
+ requirement: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ! '>='
26
+ - !ruby/object:Gem::Version
27
+ version: !binary |-
28
+ MA==
29
+ none: false
30
+ prerelease: false
31
+ type: :development
32
+ - !ruby/object:Gem::Dependency
33
+ name: trinidad
34
+ version_requirements: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: !binary |-
39
+ MA==
40
+ none: false
41
+ requirement: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: !binary |-
46
+ MA==
47
+ none: false
48
+ prerelease: false
49
+ type: :runtime
50
+ - !ruby/object:Gem::Dependency
51
+ name: sidekiq
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: !binary |-
57
+ MA==
58
+ none: false
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: !binary |-
64
+ MA==
65
+ none: false
66
+ prerelease: false
67
+ type: :runtime
68
+ description: Runs Sidekiq workers within the Trinidad application server
69
+ email:
70
+ - aemadrid@gmail.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - .gitignore
76
+ - Gemfile
77
+ - LICENSE
78
+ - README.md
79
+ - Rakefile
80
+ - lib/trinidad_sidekiq_extension.rb
81
+ - lib/trinidad_sidekiq_extension/background_manager.rb
82
+ - lib/trinidad_sidekiq_extension/lifecycle_listener.rb
83
+ - lib/trinidad_sidekiq_extension/version.rb
84
+ - trinidad_sidekiq_extension.gemspec
85
+ homepage: https://github.com/aemadrid/trinidad_sidekiq_extension
86
+ licenses: []
87
+ post_install_message:
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: !binary |-
96
+ MA==
97
+ none: false
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ! '>='
101
+ - !ruby/object:Gem::Version
102
+ version: !binary |-
103
+ MA==
104
+ none: false
105
+ requirements: []
106
+ rubyforge_project:
107
+ rubygems_version: 1.8.24
108
+ signing_key:
109
+ specification_version: 3
110
+ summary: Runs Sidekiq workers within the Trinidad application server
111
+ test_files: []