madvertise-ext 0.2.2 → 0.3.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/.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
|