edamame 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: edamame
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 17
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
8
  - 3
8
- - 0
9
- version: 0.3.0
9
+ - 1
10
+ version: 0.3.1
10
11
  platform: ruby
11
12
  authors:
12
13
  - Philip (flip) Kromer
@@ -14,16 +15,18 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-04-13 00:00:00 +00:00
18
+ date: 2010-08-16 00:00:00 +00:00
18
19
  default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
22
  name: beanstalk-client
22
23
  prerelease: false
23
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
24
26
  requirements:
25
27
  - - ">="
26
28
  - !ruby/object:Gem::Version
29
+ hash: 3
27
30
  segments:
28
31
  - 0
29
32
  version: "0"
@@ -33,9 +36,11 @@ dependencies:
33
36
  name: wukong
34
37
  prerelease: false
35
38
  requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
36
40
  requirements:
37
41
  - - ">="
38
42
  - !ruby/object:Gem::Version
43
+ hash: 3
39
44
  segments:
40
45
  - 0
41
46
  version: "0"
@@ -45,9 +50,11 @@ dependencies:
45
50
  name: monkeyshines
46
51
  prerelease: false
47
52
  requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
48
54
  requirements:
49
55
  - - ">="
50
56
  - !ruby/object:Gem::Version
57
+ hash: 3
51
58
  segments:
52
59
  - 0
53
60
  version: "0"
@@ -94,13 +101,6 @@ files:
94
101
  - lib/edamame/broker.rb
95
102
  - lib/edamame/job.rb
96
103
  - lib/edamame/monitoring.rb
97
- - lib/edamame/monitoring/README-god.textile
98
- - lib/edamame/monitoring/beanstalkd_god.rb
99
- - lib/edamame/monitoring/god_email.rb
100
- - lib/edamame/monitoring/god_process.rb
101
- - lib/edamame/monitoring/process_groups.rb
102
- - lib/edamame/monitoring/sinatra_god.rb
103
- - lib/edamame/monitoring/tyrant_god.rb
104
104
  - lib/edamame/persistent_queue.rb
105
105
  - lib/edamame/queue.rb
106
106
  - lib/edamame/queue/beanstalk.rb
@@ -134,26 +134,30 @@ rdoc_options:
134
134
  require_paths:
135
135
  - lib
136
136
  required_ruby_version: !ruby/object:Gem::Requirement
137
+ none: false
137
138
  requirements:
138
139
  - - ">="
139
140
  - !ruby/object:Gem::Version
141
+ hash: 3
140
142
  segments:
141
143
  - 0
142
144
  version: "0"
143
145
  required_rubygems_version: !ruby/object:Gem::Requirement
146
+ none: false
144
147
  requirements:
145
148
  - - ">="
146
149
  - !ruby/object:Gem::Version
150
+ hash: 3
147
151
  segments:
148
152
  - 0
149
153
  version: "0"
150
154
  requirements: []
151
155
 
152
156
  rubyforge_project:
153
- rubygems_version: 1.3.6
157
+ rubygems_version: 1.3.7
154
158
  signing_key:
155
159
  specification_version: 3
156
160
  summary: Beanstalk + Tokyo Tyrant = Edamame, a fast persistent distributed priority job queue.
157
161
  test_files:
158
- - spec/edamame_spec.rb
159
162
  - spec/spec_helper.rb
163
+ - spec/edamame_spec.rb
@@ -1,54 +0,0 @@
1
- Keep running:
2
-
3
- * Worker queue (beanstalkd)
4
- * Backing store (ttserver)
5
- * Request queue-fed Scrapers (list of scripts)
6
- * Feed/Periodic scrapers
7
- * Constant scrapers
8
-
9
- * http://god.rubyforge.org/
10
- * http://railscasts.com/episodes/130-monitoring-with-god
11
-
12
- sudo gem install god
13
- god -c config/mailit.god
14
- god status
15
- god terminate
16
- god log mailit-workling
17
- kill `cat log/workling.pid`
18
-
19
- * http://nubyonrails.com/articles/about-this-blog-beanstalk-messaging-queue
20
- ** The "god.conf":http://pastie.textmate.org/private/ovgxu2ihoicli2ktrwtbew is
21
- taken from there.
22
-
23
- h2. Beanstalkd
24
-
25
- *Usage*:
26
-
27
- beanstalkd --help
28
- Use: beanstalkd [OPTIONS]
29
-
30
- Options:
31
- -d detach
32
- -l ADDR listen on address (default is 0.0.0.0)
33
- -p PORT listen on port (default is 11300)
34
- -u USER become user and group
35
- -z SIZE set the maximum job size in bytes (default is 65535)
36
- -v show version information
37
- -h show this help
38
-
39
-
40
- h2. Tokyo Tyrant
41
-
42
- *Usage*:
43
-
44
- ttserver --help
45
- ttserver: the server of Tokyo Tyrant
46
-
47
- usage:
48
- ttserver [-host name] [-port num] [-thnum num] [-tout num] [-dmn]
49
- [-pid path] [-kl] [-log path] [-ld|-le] [-ulog path]
50
- [-ulim num] [-uas] [-sid num]
51
- [-mhost name] [-mport num] [-rts path] [-rcc] [-skel name]
52
- [-ext path] [-extpc name period] [-mask expr] [-unmask expr] [dbname]
53
-
54
-
@@ -1,28 +0,0 @@
1
- class BeanstalkdGod < GodProcess
2
- BeanstalkdGod::DEFAULT_OPTIONS = {
3
- :listen_on => '0.0.0.0',
4
- :port => 11300,
5
- :user => nil,
6
- :max_job_size => '65535',
7
- :max_cpu_usage => 50.percent,
8
- :max_mem_usage => 500.megabytes,
9
- :monitor_group => 'beanstalkds',
10
- :beanstalkd_exe => '/usr/local/bin/beanstalkd',
11
- }
12
- def self.default_options() super.deep_merge(BeanstalkdGod::DEFAULT_OPTIONS) ; end
13
- def self.site_options() super.deep_merge(global_site_options[:beanstalkd_god]||{}) ; end
14
-
15
- def self.kind
16
- :beanstalkd
17
- end
18
-
19
- def start_command
20
- [
21
- options[:beanstalkd_exe],
22
- "-l #{options[:listen_on]}",
23
- "-p #{options[:port]}",
24
- "-z #{options[:max_job_size]}",
25
- options[:user] ? "-u #{options[:user]}" : "",
26
- ].flatten.compact.join(" ")
27
- end
28
- end
@@ -1,45 +0,0 @@
1
- module God
2
- def self.setup_email options
3
- God::Contacts::Email.message_settings = {
4
- :from => options[:username], }
5
- God.contact(:email) do |c|
6
- c.name = options[:to_name]
7
- c.email = options[:to]
8
- c.group = options[:group] || 'default'
9
- end
10
- if options[:address] then delivery_by_smtp(options)
11
- else delivery_by_gmail(options) end
12
- end
13
-
14
- #
15
- # GMail
16
- #
17
- # http://millarian.com/programming/ruby-on-rails/monitoring-thin-using-god-with-google-apps-notifications/
18
- def self.delivery_by_gmail options
19
- require 'tlsmail'
20
- Net::SMTP.enable_tls(OpenSSL::SSL::VERIFY_NONE)
21
- God::Contacts::Email.server_settings = {
22
- :address => 'smtp.gmail.com',
23
- :tls => 'true',
24
- :port => 587,
25
- :domain => options[:email_domain],
26
- :user_name => options[:username],
27
- :password => options[:password],
28
- :authentication => :plain
29
- }
30
- end
31
-
32
- #
33
- # SMTP email
34
- #
35
- def self.delivery_by_smtp options
36
- God::Contacts::Email.server_settings = {
37
- :address => options[:address],
38
- :port => 25,
39
- :domain => options[:email_domain],
40
- :user_name => options[:username],
41
- :password => options[:password],
42
- :authentication => :plain,
43
- }
44
- end
45
- end
@@ -1,205 +0,0 @@
1
- class GodProcess
2
- DEFAULT_OPTIONS = {
3
- :monitor_group => nil,
4
- :uid => nil,
5
- :gid => nil,
6
- :start_notify => nil,
7
- :restart_notify => nil,
8
- :flapping_notify => nil,
9
-
10
- :process_log_dir => '/var/log/god',
11
-
12
- :start_grace_time => 20.seconds,
13
- :restart_grace_time => nil, # start_grace_time+2 if nil
14
- :default_interval => 5.minutes,
15
- :start_interval => 5.minutes,
16
- :mem_usage_interval => 20.minutes,
17
- :cpu_usage_interval => 20.minutes,
18
- }
19
- # Site options definition files. Merged in order, later entries win.
20
- GLOBAL_SITE_OPTIONS_FILES = []
21
- # merged contents of the GLOBAL_SITE_OPTIONS_FILES
22
- cattr_reader :global_site_options
23
- attr_accessor :options
24
-
25
- #
26
- # * Class options are defined by the edamame code. They define each process'
27
- # base behavior.
28
- #
29
- # * Site options are defined by config file(s), and define machine/org
30
- # specific policy (paths to daemon executables, for instance). Site options
31
- # override class options.
32
- #
33
- # * Options passed in at instantiation describe the specifics of this
34
- # particular process -- the path to a database's file, perhaps. They
35
- # override site options (and therefore class options too).
36
- #
37
- # Note that, though the options hash is preserved, if action
38
- #
39
- def initialize _options
40
- self.options = { }
41
- self.options.deep_merge! self.class.default_options
42
- self.options.deep_merge! self.class.site_options
43
- self.options.deep_merge! _options
44
- p self.options
45
- end
46
-
47
- #
48
- # Walks upwards through the inheritance tree, accumulating default
49
- # options. Later (subclass) nodes should override earlier (super) nodes, with
50
- # something like
51
- #
52
- # def self.default_options
53
- # super.deep_merge(ThisClass::DEFAULT_OPTIONS)
54
- # end
55
- #
56
- def self.default_options
57
- GodProcess::DEFAULT_OPTIONS
58
- end
59
-
60
- #
61
- # Walks upwards through the inheritance tree, accumulating site
62
- # options. Later (subclass) nodes should override earlier (super) nodes, with
63
- # something like
64
- #
65
- # def self.site_options
66
- # super.deep_merge( global_site_options[:this_class] )
67
- # end
68
- #
69
- def self.site_options
70
- global_site_options[:god_process] || {}
71
- end
72
-
73
- def self.global_site_options
74
- return @global_site_options if @globalsite_options
75
- @global_site_options = {}
76
- GLOBAL_SITE_OPTIONS_FILES.each do |options_filename|
77
- @global_site_options.deep_merge! YAML.load_file(options_filename)
78
- end
79
- @global_site_options
80
- end
81
-
82
- def setup
83
- LOG.info options.inspect
84
- God.watch do |watcher|
85
- setup_watcher watcher
86
- setup_start watcher
87
- setup_restart watcher
88
- setup_lifecycle watcher
89
- end
90
- end
91
- def self.create options={}
92
- proc = self.new options
93
- proc.setup
94
- proc.mkdirs!
95
- proc
96
- end
97
-
98
- def handle
99
- (options[:handle] || "#{self.class.kind}_#{options[:port]}").to_s
100
- end
101
-
102
- # Log file
103
- def process_log_file
104
- File.join(options[:process_log_dir], handle+".log")
105
- end
106
-
107
- # create any directories required by the process
108
- def mkdirs!
109
- require 'fileutils'
110
- FileUtils.mkdir_p File.dirname(process_log_file)
111
- end
112
-
113
- # command to start the daemon
114
- def start_command
115
- options[:start_command]
116
- end
117
- # command to stop the daemon
118
- # return nil to have god daemonize the process
119
- def stop_command
120
- options[:stop_command]
121
- end
122
- # command to restart
123
- # if stop_command is nil, it lets god daemonize the process
124
- # otherwise, by default it runs stop_command, pauses for 1 second, then runs start_command
125
- def restart_command
126
- return unless stop_command
127
- [stop_command, "sleep 1", start_command].join(" && ")
128
- end
129
-
130
- #
131
- # Setup common to most watchers
132
- #
133
- def setup_watcher watcher
134
- watcher.name = self.handle
135
- watcher.start = start_command
136
- watcher.stop = stop_command if stop_command
137
- watcher.restart = restart_command if restart_command
138
- watcher.group = options[:monitor_group] if options[:monitor_group]
139
- watcher.uid = options[:uid] if options[:uid]
140
- watcher.gid = options[:gid] if options[:gid]
141
- watcher.pid_file = options[:pid_file] if options[:pid_file]
142
- watcher.interval = options[:default_interval]
143
- watcher.start_grace = options[:start_grace_time]
144
- watcher.restart_grace = options[:restart_grace_time] || (options[:start_grace_time] + 2.seconds)
145
- watcher.behavior(:clean_pid_file)
146
- end
147
-
148
- #
149
- # Starts process
150
- #
151
- def setup_start watcher
152
- watcher.start_if do |start|
153
- start.condition(:process_running) do |c|
154
- c.interval = options[:start_interval]
155
- c.running = false
156
- c.notify = options[:start_notify] if options[:start_notify]
157
- end
158
- end
159
- end
160
-
161
- #
162
- def setup_restart watcher
163
- watcher.restart_if do |restart|
164
- restart.condition(:memory_usage) do |c|
165
- c.interval = options[:mem_usage_interval] if options[:mem_usage_interval]
166
- c.above = options[:max_mem_usage] || 150.megabytes
167
- c.times = [3, 5] # 3 out of 5 intervals
168
- c.notify = options[:restart_notify] if options[:restart_notify]
169
- end
170
- restart.condition(:cpu_usage) do |c|
171
- c.interval = options[:cpu_usage_interval] if options[:cpu_usage_interval]
172
- c.above = options[:max_cpu_usage] || 50.percent
173
- c.times = 5
174
- c.notify = options[:restart_notify] if options[:restart_notify]
175
- end
176
- end
177
- end
178
-
179
- # Define lifecycle
180
- def setup_lifecycle watcher
181
- watcher.lifecycle do |on|
182
- on.condition(:flapping) do |c|
183
- c.to_state = [:start, :restart]
184
- c.times = 10
185
- c.within = 15.minute
186
- c.transition = :unmonitored
187
- c.retry_in = 60.minutes
188
- c.retry_times = 5
189
- c.retry_within = 12.hours
190
- c.notify = options[:flapping_notify] if options[:flapping_notify]
191
- end
192
- end
193
- end
194
- end
195
-
196
- class Hash
197
- # remove all key-value pairs where the value is nil
198
- def compact
199
- reject{|key,val| val.nil? }
200
- end
201
- # Replace the hash with its compacted self
202
- def compact!
203
- replace(compact)
204
- end
205
- end
@@ -1,32 +0,0 @@
1
- module God
2
- #
3
- # Given a base port number and an associative array
4
- # [ [GodProcessSubclass, { :options => 'for factory methods', ... }],
5
- # ..., }
6
- # this creates each given service with incrementing port numbers.
7
- #
8
- # For example,
9
- #
10
- # God.service_group 12300, [
11
- # [BeanstalkdGod, { :max_mem_usage => 2.gigabytes, }],
12
- # [TyrantGod, { :db_dirname => EDAMAME_DB_DIR, :db_name => 'queue_jobs.tch' }],
13
- # [TyrantGod, { :db_dirname => EDAMAME_DB_DIR, :db_name => 'fetched_urls.tch' }],
14
- # [ThinGod, { :thin_config_yml => '/slice/www/edamame_monitor/current/config.yml' }],
15
- # ]
16
- #
17
- # will create an edamame pair of beanstalkd queue on 123000 and tyrant DB on
18
- # 12301, an app-specific DB on 12302, and a lightweight monitoring web app on
19
- # 12303.
20
- #
21
- # It's up to you to choose the ports to not overlap with other groups, etc.
22
- #
23
- # If an explicit port is given, that port is used with no regard to the rest
24
- # of the group, and its number is skipped.
25
- #
26
- def self.process_group base_port, services
27
- services.each do |klass, options|
28
- klass.create({ :port => base_port }.deep_merge(options))
29
- base_port += 1
30
- end
31
- end
32
- end
@@ -1,34 +0,0 @@
1
- class SinatraGod < GodProcess
2
- SinatraGod::DEFAULT_OPTIONS = {
3
- :monitor_group => 'sinatras',
4
- :server_exe => '/usr/bin/thin', # path to thin. Override this in the site config file.
5
- :port => 12000,
6
- :thin_config_yml => '/somedir/config.yml',
7
- :pid_file => '/var/run/god/sinatra.pid'
8
- }
9
- def self.default_options() super.deep_merge(SinatraGod::DEFAULT_OPTIONS) ; end
10
- def self.site_options() super.deep_merge(global_site_options[:sinatra_god]||{}) ; end
11
-
12
- def self.kind
13
- :sinatra
14
- end
15
-
16
- def thin_command action
17
- [ options[:server_exe], action,
18
- "--config=#{options[:thin_config_yml]}",
19
- (options[:pid_file] ? "--pid=#{options[:pid_file]}" : ''),
20
- ].flatten.compact.join(" ")
21
- end
22
-
23
- def start_command
24
- thin_command :start
25
- end
26
-
27
- def restart_command
28
- thin_command :restart
29
- end
30
-
31
- def stop_command
32
- thin_command :stop
33
- end
34
- end
@@ -1,65 +0,0 @@
1
- #
2
- # -host name : specify the host name or the address of the server. By default, every network address is bound.
3
- # -port num : specify the port number. By default, it is 1978.
4
- #
5
- # -thnum num : specify the number of worker threads. By default, it is 8.
6
- # -tout num : specify the timeout of each session in seconds. By default, no timeout is specified.
7
- #
8
- # -log path : output log messages into the file.
9
- # -ld : log debug messages also.
10
- # -le : log error messages only.
11
- # -ulog path : specify the update log directory.
12
- # -ulim num : specify the limit size of each update log file.
13
- # -uas : use asynchronous I/O for the update log.
14
- #
15
- # -sid num : specify the server ID.
16
- # -mhost name : specify the host name of the replication master server.
17
- # -mport num : specify the port number of the replication master server.
18
- # -rts path : specify the replication time stamp file.
19
- # -rcc : check consistency of replication.
20
- #
21
- # -skel name : specify the name of the skeleton database library.
22
- # -ext path : specify the script language extension file.
23
- # -extpc name period : specify the function name and the calling period of a periodic command.
24
- # -mask expr : specify the names of forbidden commands.
25
- # -unmask expr : specify the names of allowed commands.
26
- #
27
- class TyrantGod < GodProcess
28
- TyrantGod::DEFAULT_OPTIONS = {
29
- :listen_on => '0.0.0.0',
30
- :port => 11200,
31
- :db_dirname => '/tmp',
32
- #
33
- :max_cpu_usage => 50.percent,
34
- :max_mem_usage => 150.megabytes,
35
- :monitor_group => 'tyrants',
36
- :server_exe => '/usr/local/bin/ttserver',
37
- }
38
- def self.default_options() super.deep_merge(TyrantGod::DEFAULT_OPTIONS) ; end
39
- def self.site_options() super.deep_merge(global_site_options[:tyrant_god]||{}) ; end
40
-
41
- def self.kind
42
- :ttyrant
43
- end
44
-
45
- def dbname
46
- basename = options[:db_name] || (handle+'.tct')
47
- File.join(options[:db_dirname], basename)
48
- end
49
-
50
- # create any directories required by the process
51
- def mkdirs!
52
- super
53
- FileUtils.mkdir_p File.dirname(dbname)
54
- end
55
-
56
- def start_command
57
- [
58
- options[:server_exe],
59
- "-host #{options[:listen_on]}",
60
- "-port #{options[:port]}",
61
- "-log #{process_log_file}",
62
- dbname
63
- ].flatten.compact.join(" ")
64
- end
65
- end