madvertise-ext 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rvmrc +1 -1
- data/lib/madvertise/ext/array.rb +23 -0
- data/lib/madvertise/ext/config.rb +73 -40
- data/lib/madvertise/ext/hash.rb +12 -1
- data/lib/madvertise/ext/logging.rb +17 -31
- data/lib/madvertise/ext/nil.rb +5 -0
- data/lib/madvertise/ext/string.rb +3 -0
- data/lib/madvertise/ext/version.rb +1 -1
- data/lib/servolux/cli.rb +73 -0
- data/lib/servolux/wrapper.rb +51 -0
- data/madvertise-ext.gemspec +2 -0
- metadata +49 -7
data/.rvmrc
CHANGED
@@ -1 +1 @@
|
|
1
|
-
rvm use --create ruby-1.9.3-
|
1
|
+
rvm use --create ruby-1.9.3-p327@madvertise-ext
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class Array
|
2
|
+
|
3
|
+
def pick(n=1)
|
4
|
+
Array.new(n) { self[Kernel::rand(size)-1] }
|
5
|
+
end
|
6
|
+
|
7
|
+
def pick_one
|
8
|
+
self[Kernel::rand(size)-1]
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_h(&block)
|
12
|
+
Hash[*self.map { |v| [v, block.call(v)] }.flatten]
|
13
|
+
end
|
14
|
+
|
15
|
+
def / parts
|
16
|
+
inject([[]]) do |ary, x|
|
17
|
+
ary << [] if [*ary.last].nitems == length / parts
|
18
|
+
ary.last << x
|
19
|
+
ary
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -1,5 +1,8 @@
|
|
1
1
|
require 'yaml'
|
2
|
+
require 'set'
|
3
|
+
|
2
4
|
require 'madvertise/ext/hash'
|
5
|
+
require 'madvertise/ext/environment'
|
3
6
|
|
4
7
|
##
|
5
8
|
# A {Configuration} consists of one or more Sections. A section is a hash-like
|
@@ -12,14 +15,24 @@ require 'madvertise/ext/hash'
|
|
12
15
|
# => 1
|
13
16
|
#
|
14
17
|
class Section < Hash
|
18
|
+
|
15
19
|
class << self
|
16
20
|
|
21
|
+
# How to handle nil values in the configuration?
|
22
|
+
#
|
23
|
+
# Possible values are:
|
24
|
+
# - :nil, nil (return nil)
|
25
|
+
# - :raise (raise an exception)
|
26
|
+
# - :section (return a NilSection which can be chained)
|
27
|
+
#
|
28
|
+
attr_accessor :nil_action
|
29
|
+
|
17
30
|
# Create a new section from the given hash-like object.
|
18
31
|
#
|
19
32
|
# @param [Hash] hsh The hash to convert into a section.
|
20
33
|
# @return [Section] The new {Section} object.
|
21
34
|
def from_hash(hsh)
|
22
|
-
|
35
|
+
new.tap do |result|
|
23
36
|
hsh.each do |key, value|
|
24
37
|
result[key.to_sym] = from_value(value)
|
25
38
|
end
|
@@ -42,28 +55,7 @@ class Section < Hash
|
|
42
55
|
value
|
43
56
|
end
|
44
57
|
end
|
45
|
-
end
|
46
58
|
|
47
|
-
# Mixin a configuration snippet into the current section.
|
48
|
-
#
|
49
|
-
# @param [Hash, String] value A hash to merge into the current
|
50
|
-
# configuration. If a string is given a filename
|
51
|
-
# is assumed and the given file is expected to
|
52
|
-
# contain a YAML hash.
|
53
|
-
# @return [void]
|
54
|
-
def mixin(value)
|
55
|
-
unless value.is_a?(Hash)
|
56
|
-
value = Section.from_hash(YAML.load(File.read(value)))
|
57
|
-
end
|
58
|
-
|
59
|
-
self.deep_merge!(value[:default]) if value.has_key?(:default)
|
60
|
-
self.deep_merge!(value[:generic]) if value.has_key?(:generic)
|
61
|
-
|
62
|
-
if value.has_key?(@mode)
|
63
|
-
self.deep_merge!(value[@mode])
|
64
|
-
else
|
65
|
-
self.deep_merge!(value)
|
66
|
-
end
|
67
59
|
end
|
68
60
|
|
69
61
|
# Build the call chain including NilSections.
|
@@ -75,7 +67,20 @@ class Section < Hash
|
|
75
67
|
else
|
76
68
|
value = self[name]
|
77
69
|
value = value.call if value.is_a?(Proc)
|
78
|
-
|
70
|
+
|
71
|
+
if value.nil?
|
72
|
+
case self.class.nil_action
|
73
|
+
when :nil, nil
|
74
|
+
# do nothing
|
75
|
+
when :raise
|
76
|
+
raise "value is nil for key #{name}"
|
77
|
+
when :section
|
78
|
+
value = NilSection.new if value.nil?
|
79
|
+
else
|
80
|
+
raise "unknown nil handling: #{self.class.nil_action}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
79
84
|
self[name] = value
|
80
85
|
end
|
81
86
|
end
|
@@ -92,8 +97,9 @@ class Configuration < Section
|
|
92
97
|
# @param [Symbol] mode The mode to load from the configurtion file
|
93
98
|
# (production, development, etc)
|
94
99
|
# @yield [config] The new configuration object.
|
95
|
-
def initialize
|
96
|
-
@
|
100
|
+
def initialize
|
101
|
+
@mixins = Set.new
|
102
|
+
@callbacks = []
|
97
103
|
yield self if block_given?
|
98
104
|
end
|
99
105
|
|
@@ -110,25 +116,52 @@ class Configuration < Section
|
|
110
116
|
end
|
111
117
|
end
|
112
118
|
|
113
|
-
|
114
|
-
# The {Helpers} module can be included in all classes that wish to load
|
115
|
-
# configuration file(s). In order to load custom configuration files the
|
116
|
-
# including class needs to set the +@config_file+ instance variable.
|
119
|
+
# Mixin a configuration snippet into the current section.
|
117
120
|
#
|
118
|
-
|
121
|
+
# @param [Hash, String] value A hash to merge into the current
|
122
|
+
# configuration. If a string is given a filename
|
123
|
+
# is assumed and the given file is expected to
|
124
|
+
# contain a YAML hash.
|
125
|
+
# @return [void]
|
126
|
+
def mixin(value)
|
127
|
+
if value.is_a?(String)
|
128
|
+
@mixins << value
|
129
|
+
value = YAML.load(File.read(value))
|
130
|
+
end
|
119
131
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
132
|
+
value = Section.from_hash(value)
|
133
|
+
|
134
|
+
self.deep_merge!(value[:default]) if value.has_key?(:default)
|
135
|
+
self.deep_merge!(value[:generic]) if value.has_key?(:generic)
|
136
|
+
|
137
|
+
if value.has_key?(Env.to_sym)
|
138
|
+
self.deep_merge!(value[Env.to_sym])
|
139
|
+
else
|
140
|
+
self.deep_merge!(value)
|
141
|
+
end
|
142
|
+
|
143
|
+
@callbacks.each do |callback|
|
144
|
+
callback.call
|
130
145
|
end
|
131
146
|
end
|
147
|
+
|
148
|
+
# Reload all mixins.
|
149
|
+
#
|
150
|
+
# @return [void]
|
151
|
+
def reload!
|
152
|
+
self.clear
|
153
|
+
@mixins.each do |file|
|
154
|
+
self.mixin(file)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# Register a callback for config mixins.
|
159
|
+
#
|
160
|
+
# @return [void]
|
161
|
+
def callback(&block)
|
162
|
+
@callbacks << block
|
163
|
+
end
|
164
|
+
|
132
165
|
end
|
133
166
|
|
134
167
|
##
|
data/lib/madvertise/ext/hash.rb
CHANGED
@@ -12,9 +12,20 @@ class Hash
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
# Recursively merge and replace +other_hash+ into +self
|
15
|
+
# Recursively merge and replace +other_hash+ into +self+.
|
16
16
|
def deep_merge!(other_hash)
|
17
17
|
replace(deep_merge(other_hash))
|
18
18
|
end
|
19
19
|
|
20
|
+
# accumulate existing keys from +other_hash+ into +self+.
|
21
|
+
def delta_merge!(other_hash)
|
22
|
+
other_hash.each do |k,v|
|
23
|
+
if self.has_key?(k)
|
24
|
+
self[k] += v
|
25
|
+
else
|
26
|
+
self[k] = v
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
20
31
|
end
|
@@ -1,40 +1,26 @@
|
|
1
|
-
|
1
|
+
# encoding: utf-8
|
2
|
+
|
2
3
|
require 'madvertise/ext/environment'
|
3
4
|
require 'madvertise-logging'
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
#
|
8
|
-
module Logging
|
9
|
-
mattr_accessor :logger
|
10
|
-
self.logger = nil
|
6
|
+
def init_logger(progname=$0, filename=nil)
|
7
|
+
progname = File.basename(progname)
|
8
|
+
filename ||= "#{Env.mode}.log"
|
11
9
|
|
12
|
-
|
13
|
-
|
14
|
-
if Env.prod?
|
15
|
-
Madvertise::Logging::ImprovedLogger.new(:syslog, $0)
|
16
|
-
else
|
17
|
-
Madvertise::Logging::ImprovedLogger.new(STDERR, $0)
|
18
|
-
end.tap do |logger|
|
19
|
-
logger.level = :info
|
20
|
-
end
|
10
|
+
MultiLogger.new.tap do |logger|
|
11
|
+
init_multi_logger(logger, progname, filename)
|
21
12
|
end
|
13
|
+
end
|
22
14
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
# Retreive and possibly create the global logger object.
|
30
|
-
#
|
31
|
-
# @return [Logger] The logger object.
|
32
|
-
def log
|
33
|
-
::Logging.logger ||= ::Logging.create_logger
|
34
|
-
end
|
15
|
+
def init_multi_logger(logger, progname=$0, filename=nil)
|
16
|
+
if Env.dev? or Env.test?
|
17
|
+
logger.attach(ImprovedLogger.new(STDERR, progname))
|
18
|
+
else
|
19
|
+
logger.attach(ImprovedLogger.new(:syslog, progname))
|
35
20
|
end
|
36
|
-
end
|
37
21
|
|
38
|
-
|
39
|
-
|
22
|
+
# default log level
|
23
|
+
logger.level = Logger::INFO
|
40
24
|
end
|
25
|
+
|
26
|
+
$log = init_logger
|
data/lib/servolux/cli.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'madvertise/ext/environment'
|
4
|
+
require 'mixlib/cli'
|
5
|
+
require 'servolux'
|
6
|
+
|
7
|
+
module Servolux
|
8
|
+
class BaseCLI
|
9
|
+
include Mixlib::CLI
|
10
|
+
|
11
|
+
def self.inherited(subclass)
|
12
|
+
subclass.option :environment,
|
13
|
+
:short => '-e ENVIRONMENT',
|
14
|
+
:long => '--environment ENVIRONMENT',
|
15
|
+
:description => "Set the daemon environment",
|
16
|
+
:default => "development",
|
17
|
+
:proc => ->(value) { Env.set(value) }
|
18
|
+
|
19
|
+
subclass.option :debug,
|
20
|
+
:short => '-D',
|
21
|
+
:long => '--debug',
|
22
|
+
:description => "Enable debug output",
|
23
|
+
:boolean => true,
|
24
|
+
:default => false
|
25
|
+
|
26
|
+
subclass.option :help,
|
27
|
+
:short => '-h',
|
28
|
+
:long => '--help',
|
29
|
+
:description => "Show this message",
|
30
|
+
:on => :tail,
|
31
|
+
:boolean => true,
|
32
|
+
:show_options => true,
|
33
|
+
:exit => 0
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.parse_options
|
37
|
+
new.tap do |cli|
|
38
|
+
cli.parse_options
|
39
|
+
end.config
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class CLI < BaseCLI
|
44
|
+
end
|
45
|
+
|
46
|
+
class DaemonCLI < BaseCLI
|
47
|
+
option :name,
|
48
|
+
:short => '-n NAME',
|
49
|
+
:long => '--name NAME',
|
50
|
+
:description => 'Process name',
|
51
|
+
:default => $0,
|
52
|
+
:proc => ->(value) { $0 = value }
|
53
|
+
|
54
|
+
option :pidfile,
|
55
|
+
:short => '-p PIDFILE',
|
56
|
+
:long => '--pidfile PIDFILE',
|
57
|
+
:description => "The daemon pidfile",
|
58
|
+
:default => "#{$0}.pid"
|
59
|
+
|
60
|
+
option :daemonize,
|
61
|
+
:short => '-d',
|
62
|
+
:long => '--daemonize',
|
63
|
+
:description => "Daemonize the server process",
|
64
|
+
:boolean => true,
|
65
|
+
:default => false
|
66
|
+
|
67
|
+
option :kill,
|
68
|
+
:short => '-k',
|
69
|
+
:long => '--kill',
|
70
|
+
:description => "Kill the currently running daemon instance",
|
71
|
+
:boolean => true
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'madvertise/ext/logging'
|
4
|
+
require 'servolux'
|
5
|
+
require 'servolux/cli'
|
6
|
+
|
7
|
+
module Servolux
|
8
|
+
def self.init_config(cli_class)
|
9
|
+
config = cli_class.parse_options
|
10
|
+
|
11
|
+
# CLI.parse_options may have changed $0
|
12
|
+
# so we reload the logger for good measure
|
13
|
+
$log = init_logger
|
14
|
+
$log.level = config[:debug] ? :debug : :info
|
15
|
+
|
16
|
+
return config
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.wrap(server_class)
|
20
|
+
config = self.init_config(Servolux::CLI)
|
21
|
+
server_class.new(config).run
|
22
|
+
rescue => e
|
23
|
+
$log.exception(e)
|
24
|
+
raise e
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.wrap_daemon(server_class)
|
28
|
+
config = self.init_config(Servolux::DaemonCLI)
|
29
|
+
|
30
|
+
server = server_class.new(config[:name], config.merge({
|
31
|
+
interval: 1,
|
32
|
+
logger: $log,
|
33
|
+
pid_file: config[:pidfile]
|
34
|
+
}))
|
35
|
+
|
36
|
+
if config[:daemonize] or config[:kill]
|
37
|
+
daemon = Servolux::Daemon.new(:server => server)
|
38
|
+
|
39
|
+
if config[:kill]
|
40
|
+
daemon.shutdown
|
41
|
+
else
|
42
|
+
daemon.startup
|
43
|
+
end
|
44
|
+
else
|
45
|
+
server.startup
|
46
|
+
end
|
47
|
+
rescue => e
|
48
|
+
$log.exception(e)
|
49
|
+
raise e
|
50
|
+
end
|
51
|
+
end
|
data/madvertise-ext.gemspec
CHANGED
@@ -11,6 +11,8 @@ Gem::Specification.new do |gem|
|
|
11
11
|
gem.homepage = "https://github.com/madvertise/ext"
|
12
12
|
|
13
13
|
gem.add_dependency "madvertise-logging"
|
14
|
+
gem.add_dependency "mixlib-cli"
|
15
|
+
gem.add_dependency "servolux"
|
14
16
|
|
15
17
|
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
16
18
|
gem.files = `git ls-files`.split("\n")
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: madvertise-ext
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: madvertise-logging
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,44 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: mixlib-cli
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: servolux
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
25
62
|
description: Ruby extensions
|
26
63
|
email:
|
27
64
|
- benedikt.boehm@madvertise.com
|
@@ -37,14 +74,19 @@ files:
|
|
37
74
|
- LICENSE
|
38
75
|
- README.md
|
39
76
|
- Rakefile
|
77
|
+
- lib/madvertise/ext/array.rb
|
40
78
|
- lib/madvertise/ext/config.rb
|
41
79
|
- lib/madvertise/ext/enumerable.rb
|
42
80
|
- lib/madvertise/ext/environment.rb
|
43
81
|
- lib/madvertise/ext/hash.rb
|
44
82
|
- lib/madvertise/ext/logging.rb
|
45
83
|
- lib/madvertise/ext/mask.reek
|
84
|
+
- lib/madvertise/ext/nil.rb
|
85
|
+
- lib/madvertise/ext/string.rb
|
46
86
|
- lib/madvertise/ext/transaction_id.rb
|
47
87
|
- lib/madvertise/ext/version.rb
|
88
|
+
- lib/servolux/cli.rb
|
89
|
+
- lib/servolux/wrapper.rb
|
48
90
|
- madvertise-ext.gemspec
|
49
91
|
- spec/enumerable_spec.rb
|
50
92
|
- spec/spec.opts
|
@@ -66,7 +108,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
66
108
|
version: '0'
|
67
109
|
segments:
|
68
110
|
- 0
|
69
|
-
hash:
|
111
|
+
hash: -2076914703053798103
|
70
112
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
113
|
none: false
|
72
114
|
requirements:
|
@@ -75,10 +117,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
117
|
version: '0'
|
76
118
|
segments:
|
77
119
|
- 0
|
78
|
-
hash:
|
120
|
+
hash: -2076914703053798103
|
79
121
|
requirements: []
|
80
122
|
rubyforge_project:
|
81
|
-
rubygems_version: 1.8.
|
123
|
+
rubygems_version: 1.8.24
|
82
124
|
signing_key:
|
83
125
|
specification_version: 3
|
84
126
|
summary: Ruby extensions
|