edamame 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.textile +20 -0
- data/README.textile +90 -0
- data/app/edamame_san/config.ru +4 -0
- data/app/edamame_san/config.yml +17 -0
- data/app/edamame_san/edamame_san.rb +71 -0
- data/app/edamame_san/public/favicon.ico +0 -0
- data/app/edamame_san/public/images/edamame_logo.icns +0 -0
- data/app/edamame_san/public/images/edamame_logo.ico +0 -0
- data/app/edamame_san/public/images/edamame_logo.png +0 -0
- data/app/edamame_san/public/images/edamame_logo_2.icns +0 -0
- data/app/edamame_san/public/javascripts/application.js +8 -0
- data/app/edamame_san/public/javascripts/jquery/jquery-ui.js +8694 -0
- data/app/edamame_san/public/javascripts/jquery/jquery.js +4376 -0
- data/app/edamame_san/public/stylesheets/application.css +32 -0
- data/app/edamame_san/public/stylesheets/layout.css +88 -0
- data/app/edamame_san/views/layout.haml +13 -0
- data/app/edamame_san/views/load.haml +37 -0
- data/app/edamame_san/views/root.haml +25 -0
- data/bin/edamame-nuke +20 -0
- data/bin/edamame-ps +2 -0
- data/bin/edamame-stats +13 -0
- data/bin/edamame-sync +21 -0
- data/bin/edamame_util_opts.rb +10 -0
- data/bin/test_run.rb +14 -0
- data/lib/edamame.rb +29 -0
- data/lib/edamame/broker.rb +38 -0
- data/lib/edamame/job.rb +114 -0
- data/lib/edamame/monitoring.rb +7 -0
- data/lib/edamame/monitoring/README-god.textile +54 -0
- data/lib/edamame/monitoring/beanstalkd_god.rb +28 -0
- data/lib/edamame/monitoring/god_email.rb +45 -0
- data/lib/edamame/monitoring/god_process.rb +205 -0
- data/lib/edamame/monitoring/process_groups.rb +32 -0
- data/lib/edamame/monitoring/sinatra_god.rb +34 -0
- data/lib/edamame/monitoring/tyrant_god.rb +59 -0
- data/lib/edamame/persistent_queue.rb +152 -0
- data/lib/edamame/queue.rb +6 -0
- data/lib/edamame/queue/beanstalk.rb +134 -0
- data/lib/edamame/scheduling.rb +79 -0
- data/lib/edamame/store.rb +8 -0
- data/lib/edamame/store/base.rb +62 -0
- data/lib/edamame/store/tyrant_store.rb +49 -0
- data/lib/methods.txt +94 -0
- data/spec/edamame_spec.rb +7 -0
- data/spec/spec_helper.rb +10 -0
- data/utils/god/edamame.god +36 -0
- data/utils/god/edamame.yaml +61 -0
- data/utils/god/god-etc-init-dot-d-example +40 -0
- data/utils/god/god.conf +22 -0
- data/utils/god/god_site_config.rb +4 -0
- data/utils/god/wuclan.god +36 -0
- data/utils/simulation/Add Percent Variation.vi +0 -0
- data/utils/simulation/Harmonic Average.vi +0 -0
- data/utils/simulation/Rescheduling Simulation.aliases +3 -0
- data/utils/simulation/Rescheduling Simulation.lvlps +3 -0
- data/utils/simulation/Rescheduling Simulation.lvproj +22 -0
- data/utils/simulation/Rescheduling.vi +0 -0
- data/utils/simulation/Weighted Average.vi +0 -0
- metadata +147 -0
@@ -0,0 +1,7 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'edamame/monitoring/god_process'
|
3
|
+
require 'edamame/monitoring/god_email'
|
4
|
+
require 'edamame/monitoring/beanstalkd_god'
|
5
|
+
require 'edamame/monitoring/tyrant_god'
|
6
|
+
require 'edamame/monitoring/sinatra_god'
|
7
|
+
require 'edamame/monitoring/process_groups'
|
@@ -0,0 +1,54 @@
|
|
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
|
+
|
@@ -0,0 +1,28 @@
|
|
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
|
@@ -0,0 +1,45 @@
|
|
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
|
@@ -0,0 +1,205 @@
|
|
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
|
@@ -0,0 +1,32 @@
|
|
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
|
@@ -0,0 +1,34 @@
|
|
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
|
@@ -0,0 +1,59 @@
|
|
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
|
+
def start_command
|
51
|
+
[
|
52
|
+
options[:server_exe],
|
53
|
+
"-host #{options[:listen_on]}",
|
54
|
+
"-port #{options[:port]}",
|
55
|
+
"-log #{process_log_file}",
|
56
|
+
dbname
|
57
|
+
].flatten.compact.join(" ")
|
58
|
+
end
|
59
|
+
end
|