minus5_daemon 0.2.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/Rakefile +14 -0
- data/lib/minus5_daemon/base.rb +58 -0
- data/lib/minus5_daemon/capistrano_deploy.rb +1 -0
- data/lib/minus5_daemon/em_base.rb +36 -0
- data/lib/minus5_daemon/runner.rb +125 -0
- data/lib/minus5_daemon.rb +16 -0
- data/tasks/capistrano_deploy.rb +54 -0
- metadata +88 -0
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "rake/testtask"
|
2
|
+
require 'rubygems/package_task'
|
3
|
+
load 'minus5_daemon.gemspec'
|
4
|
+
|
5
|
+
task :default => [:test]
|
6
|
+
|
7
|
+
Rake::TestTask.new do |test|
|
8
|
+
test.libs << "test"
|
9
|
+
test.test_files = Dir[ "test/test_*.rb" ]
|
10
|
+
test.verbose = true
|
11
|
+
end
|
12
|
+
|
13
|
+
Gem::PackageTask.new(GEMSPEC) do |pkg|
|
14
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Minus5
|
2
|
+
module Daemon
|
3
|
+
|
4
|
+
class Base
|
5
|
+
|
6
|
+
def initialize(options, logger)
|
7
|
+
@options = options
|
8
|
+
@logger = logger
|
9
|
+
@active = true
|
10
|
+
@sleep_interval = 1
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_reader :logger
|
14
|
+
|
15
|
+
def run
|
16
|
+
on_start
|
17
|
+
Signal.trap("TERM") do
|
18
|
+
logger.debug "TERM signal received"
|
19
|
+
@active = false
|
20
|
+
on_stop
|
21
|
+
end
|
22
|
+
while @active
|
23
|
+
run_loop
|
24
|
+
sleep_with_check
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
protected
|
29
|
+
|
30
|
+
# sleep for delay, but check at least every second if TERM signal is received
|
31
|
+
def sleep_with_check
|
32
|
+
if @sleep_interval < 1
|
33
|
+
Kernel::sleep @sleep_interval
|
34
|
+
return
|
35
|
+
end
|
36
|
+
elapsed = 0
|
37
|
+
while @active && elapsed < @sleep_interval
|
38
|
+
Kernel::sleep((@sleep_interval - elapsed < 1) ? (@sleep_interval - elapsed) : 1)
|
39
|
+
elapsed = elapsed + 1
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def on_start
|
44
|
+
logger.debug "on_start"
|
45
|
+
end
|
46
|
+
|
47
|
+
def run_loop
|
48
|
+
logger.debug "run_loop"
|
49
|
+
end
|
50
|
+
|
51
|
+
def on_stop
|
52
|
+
logger.debug "on_stop"
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../../tasks/capistrano_deploy.rb"
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'eventmachine'
|
3
|
+
|
4
|
+
module Minus5
|
5
|
+
module Daemon
|
6
|
+
|
7
|
+
class EmBase
|
8
|
+
|
9
|
+
def initialize(options, logger)
|
10
|
+
@options = options
|
11
|
+
@logger = logger
|
12
|
+
end
|
13
|
+
|
14
|
+
def run
|
15
|
+
EventMachine.run do
|
16
|
+
self.em_run
|
17
|
+
logger.debug "em - server started"
|
18
|
+
Signal.trap("TERM") do
|
19
|
+
logger.debug "em - TERM signal received"
|
20
|
+
EventMachine::stop_event_loop
|
21
|
+
EventMachine::stop
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
def em_run
|
29
|
+
end
|
30
|
+
|
31
|
+
attr_reader :logger
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
module Minus5
|
2
|
+
module Daemon
|
3
|
+
|
4
|
+
def self.run(klass)
|
5
|
+
Runner.new(klass).run
|
6
|
+
rescue => e
|
7
|
+
print "#{e}\n"
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
class Runner
|
12
|
+
|
13
|
+
def initialize(klass = nil)
|
14
|
+
@klass = klass
|
15
|
+
# asserts
|
16
|
+
init_logger
|
17
|
+
@options = OpenStruct.new(
|
18
|
+
:daemonize => true,
|
19
|
+
:config_file => 'config.yml',
|
20
|
+
:config_file_set => false,
|
21
|
+
:environment => 'production',
|
22
|
+
:app_name => start_script_name,
|
23
|
+
:app_root => app_root)
|
24
|
+
parse_arg_options
|
25
|
+
load_config
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :logger
|
29
|
+
|
30
|
+
def run
|
31
|
+
mkdirs
|
32
|
+
Daemons.run_proc(@options.app_name, daemon_options) do
|
33
|
+
logger.info "starting daemon pid: #{Process.pid}"
|
34
|
+
logger.debug "options: #{@options}"
|
35
|
+
service = @klass.new(@options, @logger)
|
36
|
+
service.run
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def load_config
|
43
|
+
config_file = "#{@options.app_root}/config/#{@options.config_file}"
|
44
|
+
if File.exists?(config_file)
|
45
|
+
@options.config = YAML.load_file config_file
|
46
|
+
else
|
47
|
+
if @options.config_file_set
|
48
|
+
msg = "config file #{config_file} not found"
|
49
|
+
@logger.error msg
|
50
|
+
raise msg
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def init_logger
|
56
|
+
@logger = Logger.new(STDOUT)
|
57
|
+
@logger.level = Logger::DEBUG
|
58
|
+
@logger.datetime_format = "%H:%M:%S"
|
59
|
+
@logger.formatter = proc { |severity, datetime, progname, msg|
|
60
|
+
"#{datetime.strftime("%Y-%m-%d %H:%M:%S")} #{severity}: #{msg}\n"
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
def parse_arg_options
|
65
|
+
opts = OptionParser.new do |opts|
|
66
|
+
opts.banner = "Usage: #{start_script_name} [options]"
|
67
|
+
opts.separator ''
|
68
|
+
opts.on('-n','--no-daemonize',"Don't run as a daemon") do
|
69
|
+
@options.daemonize = false
|
70
|
+
end
|
71
|
+
opts.on('-e','--environment=name',"Specifies the environment to run this server under. Default: production") do |name|
|
72
|
+
@options.environment = name
|
73
|
+
end
|
74
|
+
opts.on('-c','--config=file',"Use specified config file. This is yaml config file name from app_root/config dir.") do |file|
|
75
|
+
file = "#{file}.yml" unless file.include?(".")
|
76
|
+
@options.config_file = file
|
77
|
+
@options.config_file_set = true
|
78
|
+
end
|
79
|
+
opts.on('-a','--app-name=file',"Use specified application name for daemon process.") do |name|
|
80
|
+
@options.app_name = name
|
81
|
+
end
|
82
|
+
end
|
83
|
+
@args = opts.parse!(ARGV)
|
84
|
+
end
|
85
|
+
|
86
|
+
def daemon_options
|
87
|
+
{
|
88
|
+
:backtrace => true,
|
89
|
+
:dir_mode => :normal,
|
90
|
+
:log_output => true,
|
91
|
+
:dir => pid_dir,
|
92
|
+
:log_dir => log_dir,
|
93
|
+
:ARGV => @args,
|
94
|
+
:ontop => !@options.daemonize
|
95
|
+
}
|
96
|
+
end
|
97
|
+
|
98
|
+
def mkdirs
|
99
|
+
FileUtils.mkdir_p pid_dir
|
100
|
+
FileUtils.mkdir_p log_dir
|
101
|
+
end
|
102
|
+
|
103
|
+
def log_dir
|
104
|
+
"#{app_root}/log"
|
105
|
+
end
|
106
|
+
|
107
|
+
def pid_dir
|
108
|
+
"#{app_root}/tmp/pids"
|
109
|
+
end
|
110
|
+
|
111
|
+
def start_script_name
|
112
|
+
File.basename($0)
|
113
|
+
end
|
114
|
+
|
115
|
+
def app_root
|
116
|
+
start_dir = File.expand_path(File.dirname($0))
|
117
|
+
root_rel = ""
|
118
|
+
root_rel = ".." if start_dir.end_with?("/lib") || start_dir.end_with?("/bin")
|
119
|
+
File.expand_path(File.join(File.dirname($0), root_rel))
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#core lib
|
2
|
+
require 'fileutils'
|
3
|
+
require 'optparse'
|
4
|
+
require 'logger'
|
5
|
+
require 'ostruct'
|
6
|
+
require 'yaml'
|
7
|
+
#gems
|
8
|
+
require 'rubygems'
|
9
|
+
|
10
|
+
gem 'daemons', '= 1.1.3'
|
11
|
+
require 'daemons'
|
12
|
+
|
13
|
+
$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/minus5_daemon/"
|
14
|
+
require 'runner.rb'
|
15
|
+
require 'base.rb'
|
16
|
+
require 'em_base.rb'
|
@@ -0,0 +1,54 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
|
3
|
+
#start stop deamon
|
4
|
+
namespace :deploy do
|
5
|
+
desc "Restarting daemon"
|
6
|
+
task :restart do
|
7
|
+
run "#{current_path}/lib/#{application}.rb restart"
|
8
|
+
end
|
9
|
+
|
10
|
+
desc "Stopping daemon"
|
11
|
+
task :stop do
|
12
|
+
run "#{current_path}/lib/#{application}.rb stop"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
after "deploy:setup", "fix_dir_permissions"
|
17
|
+
desc "change group to deploy_group on dirs created during deploy:setup"
|
18
|
+
task :fix_dir_permissions do
|
19
|
+
dirs = [deploy_to, releases_path, shared_path]
|
20
|
+
dirs += shared_children.map { |d| File.join(shared_path, d) }
|
21
|
+
group = deploy_group || "admin"
|
22
|
+
run "#{try_sudo} chgrp #{group} #{dirs.join(' ')}"
|
23
|
+
end
|
24
|
+
|
25
|
+
#shared files handling (next three tasks)
|
26
|
+
#shared files are symlinked from shared to the same location in release_path for each deploy
|
27
|
+
#initiali empty files are created during deploy:setup
|
28
|
+
#if file exists in relase_path it is deleted and then replaced with symlink to shared
|
29
|
+
before "deploy:setup", "add_shard_files_to_shared_children"
|
30
|
+
task :add_shard_files_to_shared_children do
|
31
|
+
next unless exists?(:shared_files)
|
32
|
+
shared_files.each do |file|
|
33
|
+
shared_children << File.dirname(file)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
after "deploy:setup", "create_shared_files"
|
38
|
+
task :create_shared_files do
|
39
|
+
next unless exists?(:shared_files)
|
40
|
+
shared_files.each do |file|
|
41
|
+
run "touch #{shared_path}/#{file}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
after "deploy:update_code", "symlink_shared_files"
|
46
|
+
task :symlink_shared_files do
|
47
|
+
next unless exists?(:shared_files)
|
48
|
+
shared_files.each do |file|
|
49
|
+
run "rm -f #{release_path}/#{file}"
|
50
|
+
run "ln -nfs #{shared_path}/#{file} #{release_path}/#{file}"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: minus5_daemon
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Igor Anic
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-05-31 00:00:00 +02:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: daemons
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 21
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 1
|
33
|
+
- 3
|
34
|
+
version: 1.1.3
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
description: " minus5_daemon is a simple lib for crating Ruby daemons\n it is built on top daemons.rb (http://daemons.rubyforge.org/)\n"
|
38
|
+
email: ianic@minus5.hr
|
39
|
+
executables: []
|
40
|
+
|
41
|
+
extensions: []
|
42
|
+
|
43
|
+
extra_rdoc_files: []
|
44
|
+
|
45
|
+
files:
|
46
|
+
- lib/minus5_daemon.rb
|
47
|
+
- lib/minus5_daemon/base.rb
|
48
|
+
- lib/minus5_daemon/capistrano_deploy.rb
|
49
|
+
- lib/minus5_daemon/em_base.rb
|
50
|
+
- lib/minus5_daemon/runner.rb
|
51
|
+
- tasks/capistrano_deploy.rb
|
52
|
+
- Rakefile
|
53
|
+
has_rdoc: true
|
54
|
+
homepage: http://www.minus5.hr
|
55
|
+
licenses: []
|
56
|
+
|
57
|
+
post_install_message:
|
58
|
+
rdoc_options: []
|
59
|
+
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
hash: 3
|
68
|
+
segments:
|
69
|
+
- 0
|
70
|
+
version: "0"
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
hash: 3
|
77
|
+
segments:
|
78
|
+
- 0
|
79
|
+
version: "0"
|
80
|
+
requirements: []
|
81
|
+
|
82
|
+
rubyforge_project:
|
83
|
+
rubygems_version: 1.5.3
|
84
|
+
signing_key:
|
85
|
+
specification_version: 3
|
86
|
+
summary: minus5 daemon library
|
87
|
+
test_files: []
|
88
|
+
|