archfiend 0.1.0 → 0.1.1
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +7 -0
- data/CHANGES.md +12 -1
- data/Gemfile.lock +13 -14
- data/README.md +1 -0
- data/ROADMAP.md +0 -1
- data/archfiend.gemspec +7 -8
- data/exe/archfiend +1 -2
- data/lib/archfiend.rb +3 -6
- data/lib/archfiend/application.rb +3 -3
- data/lib/archfiend/cli.rb +9 -0
- data/lib/archfiend/core_ext/string/camelize.rb +17 -0
- data/lib/archfiend/core_ext/string/underscore.rb +19 -0
- data/lib/archfiend/daemon.rb +91 -0
- data/lib/archfiend/generators/daemon.rb +7 -2
- data/lib/archfiend/generators/daemon/templates/.rubocop.yml +3 -0
- data/lib/archfiend/generators/daemon/templates/Gemfile.tt +0 -1
- data/lib/archfiend/generators/daemon/templates/config/daemon.rb.tt +7 -6
- data/lib/archfiend/generators/daemon/templates/config/settings.yml.tt +3 -0
- data/lib/archfiend/generators/daemon/templates/config/settings/production.yml.tt +0 -2
- data/lib/archfiend/generators/daemon/templates/config/settings/staging.yml.tt +0 -3
- data/lib/archfiend/generators/extensions.rb +1 -0
- data/lib/archfiend/generators/options.rb +1 -1
- data/lib/archfiend/logging.rb +28 -3
- data/lib/archfiend/logging/json_formatter.rb +2 -0
- data/lib/archfiend/subprocess_loop.rb +2 -1
- data/lib/archfiend/thread_loop.rb +1 -1
- data/lib/archfiend/version.rb +1 -1
- data/scripts/travis/checks/footprint.rb +44 -0
- data/scripts/travis/install +1 -0
- data/scripts/travis/script +16 -1
- metadata +35 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c3da75a32a3781eb07875c29e6fab8396d46816f3edd3f70be40b1ddc82a1a2a
|
4
|
+
data.tar.gz: 71991d1c7c54a07cafe05a8f3f84c45967720fb82e79ac54b64be1063ec5d6af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c7f72dad45fdbd1a44c4293dc81620fb21641facf6188f4c244a9af634c7ff1133fdd186576146212ef6e6864045e5268607f92b86d0fdfe64818baac8da630
|
7
|
+
data.tar.gz: ba6877dce648fb856e9b2a060c78b8ad3a2c8fcd64c181d14e9eebc3bf77e31e5fed41b4499547a5ec68d0a2714478bfe9a2a549f560e98eefd811b6b31ab83f
|
data/.rubocop.yml
CHANGED
data/CHANGES.md
CHANGED
@@ -3,7 +3,18 @@
|
|
3
3
|
All notable changes to this project will be documented in this file, in reverse chronological order.
|
4
4
|
|
5
5
|
## [master]
|
6
|
-
[master]: https://github.com/toptal/archfiend/compare/
|
6
|
+
[master]: https://github.com/toptal/archfiend/compare/0.1.1...HEAD
|
7
|
+
|
8
|
+
## 0.1.1 (2019-01-14)
|
9
|
+
[0.1.1]: https://github.com/toptal/archfiend/compare/0.1.0...0.1.1
|
10
|
+
|
11
|
+
* daemons gem removed in favor of Process.daemon
|
12
|
+
* add formatter setting for all loggers
|
13
|
+
* fix the usage of Forwardable
|
14
|
+
* split requires for runtime and cli phases
|
15
|
+
|
16
|
+
## 0.1.0 (2018-10-10)
|
17
|
+
[0.1.0]: https://github.com/toptal/archfiend/compare/13d855f...0.1.0
|
7
18
|
|
8
19
|
### Changes:
|
9
20
|
|
data/Gemfile.lock
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
archfiend (0.1.
|
5
|
-
|
6
|
-
|
7
|
-
pry
|
8
|
-
thor
|
4
|
+
archfiend (0.1.1)
|
5
|
+
oj (~> 3.6)
|
6
|
+
thor (~> 0.20)
|
9
7
|
|
10
8
|
GEM
|
11
9
|
remote: https://rubygems.org/
|
@@ -63,7 +61,7 @@ GEM
|
|
63
61
|
jaro_winkler (1.5.1)
|
64
62
|
method_source (0.9.0)
|
65
63
|
minitest (5.11.3)
|
66
|
-
oj (3.6
|
64
|
+
oj (3.7.6)
|
67
65
|
parallel (1.12.1)
|
68
66
|
parser (2.5.1.2)
|
69
67
|
ast (~> 2.4.0)
|
@@ -87,7 +85,7 @@ GEM
|
|
87
85
|
diff-lcs (>= 1.2.0, < 2.0)
|
88
86
|
rspec-support (~> 3.8.0)
|
89
87
|
rspec-support (3.8.0)
|
90
|
-
rubocop (0.
|
88
|
+
rubocop (0.59.2)
|
91
89
|
jaro_winkler (~> 1.5.1)
|
92
90
|
parallel (~> 1.10)
|
93
91
|
parser (>= 2.5, != 2.5.1.1)
|
@@ -95,10 +93,10 @@ GEM
|
|
95
93
|
rainbow (>= 2.2.2, < 4.0)
|
96
94
|
ruby-progressbar (~> 1.7)
|
97
95
|
unicode-display_width (~> 1.0, >= 1.0.1)
|
98
|
-
rubocop-rspec (1.
|
96
|
+
rubocop-rspec (1.30.0)
|
99
97
|
rubocop (>= 0.58.0)
|
100
98
|
ruby-progressbar (1.10.0)
|
101
|
-
thor (0.20.
|
99
|
+
thor (0.20.3)
|
102
100
|
thread_safe (0.3.6)
|
103
101
|
tzinfo (1.2.5)
|
104
102
|
thread_safe (~> 0.1)
|
@@ -108,15 +106,16 @@ PLATFORMS
|
|
108
106
|
ruby
|
109
107
|
|
110
108
|
DEPENDENCIES
|
111
|
-
activerecord
|
109
|
+
activerecord (~> 5)
|
112
110
|
archfiend!
|
113
111
|
bundler (~> 1.15)
|
114
|
-
config
|
112
|
+
config (~> 1.7)
|
115
113
|
pg (~> 0.21)
|
114
|
+
pry (~> 0.11)
|
116
115
|
rake (~> 10.0)
|
117
116
|
rspec (~> 3.0)
|
118
|
-
rubocop
|
119
|
-
rubocop-rspec
|
117
|
+
rubocop (~> 0.59)
|
118
|
+
rubocop-rspec (~> 1.30)
|
120
119
|
|
121
120
|
BUNDLED WITH
|
122
|
-
1.
|
121
|
+
1.17.1
|
data/README.md
CHANGED
@@ -4,6 +4,7 @@ Archfiend (/ˈɑrtʃˈfind/) - a basic daemon generator. It features boilerplate
|
|
4
4
|
handles daemonizing, configuration, logging and more. It provides a way to structure backend applications in an organized manner.
|
5
5
|
|
6
6
|
[](https://travis-ci.com/toptal/archfiend)
|
7
|
+
[](https://badge.fury.io/rb/archfiend)
|
7
8
|
|
8
9
|
## Contents
|
9
10
|
* [Getting started](#getting-started)
|
data/ROADMAP.md
CHANGED
@@ -5,7 +5,6 @@ The general goal of this project is to have a low-dependency, solid, pluggable R
|
|
5
5
|
Ideas include
|
6
6
|
* exhaustive documentation for running (`bin/start`, `bin/console`) and development of generated daemons
|
7
7
|
* method to opt-out from any integrated gem
|
8
|
-
* removal of `daemons` dependency
|
9
8
|
* removal of `config` dependency
|
10
9
|
* removal of `clockwork` dependency
|
11
10
|
* stand-alone generator option, to generate daemons with no external run time dependencies (with Archfiend base classes baked in)
|
data/archfiend.gemspec
CHANGED
@@ -20,16 +20,15 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
21
|
spec.require_paths = ['lib']
|
22
22
|
|
23
|
-
spec.
|
24
|
-
spec.add_development_dependency 'activerecord'
|
23
|
+
spec.add_development_dependency 'activerecord', '~> 5' # For specs
|
25
24
|
spec.add_development_dependency 'bundler', '~> 1.15'
|
26
|
-
spec.add_development_dependency 'config'
|
27
|
-
spec.add_dependency 'oj'
|
25
|
+
spec.add_development_dependency 'config', '~> 1.7'
|
26
|
+
spec.add_dependency 'oj', '~> 3.6'
|
28
27
|
spec.add_development_dependency 'pg', '~> 0.21'
|
29
|
-
spec.
|
28
|
+
spec.add_development_dependency 'pry', '~> 0.11'
|
30
29
|
spec.add_development_dependency 'rake', '~> 10.0'
|
31
30
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
32
|
-
spec.add_development_dependency 'rubocop'
|
33
|
-
spec.add_development_dependency 'rubocop-rspec'
|
34
|
-
spec.add_dependency 'thor' # CLI
|
31
|
+
spec.add_development_dependency 'rubocop', '~> 0.59'
|
32
|
+
spec.add_development_dependency 'rubocop-rspec', '~> 1.30'
|
33
|
+
spec.add_dependency 'thor', '~> 0.20' # CLI
|
35
34
|
end
|
data/exe/archfiend
CHANGED
data/lib/archfiend.rb
CHANGED
@@ -1,18 +1,15 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
1
3
|
require 'archfiend/version'
|
2
4
|
require 'archfiend/application'
|
3
5
|
require 'archfiend/logging'
|
4
6
|
require 'archfiend/logging/base_formatter'
|
5
7
|
require 'archfiend/logging/default_formatter'
|
6
|
-
require 'archfiend/logging/json_formatter'
|
7
8
|
require 'archfiend/logging/multi_logger'
|
8
9
|
require 'archfiend/shared_loop/runnable'
|
9
10
|
require 'archfiend/thread_loop'
|
10
11
|
require 'archfiend/subprocess_loop'
|
11
|
-
require 'archfiend/
|
12
|
-
require 'archfiend/generators/options'
|
13
|
-
require 'archfiend/generators/extensions'
|
14
|
-
require 'archfiend/generators/utils'
|
15
|
-
require 'archfiend/cli'
|
12
|
+
require 'archfiend/daemon'
|
16
13
|
|
17
14
|
module Archfiend
|
18
15
|
end
|
@@ -1,15 +1,14 @@
|
|
1
1
|
module Archfiend
|
2
2
|
class Application
|
3
|
-
extend Forwardable
|
3
|
+
extend ::Forwardable
|
4
4
|
|
5
5
|
def_delegators :utils, :logger, :env, :name
|
6
6
|
|
7
7
|
# The main application entry point, it starts up all the subthreads, all the subprocesses,
|
8
8
|
# registers the exit handler and then it blocks the execution.
|
9
9
|
def run
|
10
|
-
logger.info 'Starting up'
|
11
|
-
|
12
10
|
setup
|
11
|
+
logger.info 'Starting up'
|
13
12
|
|
14
13
|
ThreadLoop.start_all(self)
|
15
14
|
SubprocessLoop.start_all(self)
|
@@ -80,6 +79,7 @@ module Archfiend
|
|
80
79
|
def setup_logger
|
81
80
|
logger_level = Settings.logger&.level
|
82
81
|
fail "Please set logger.level setting (#{POSSIBLE_LOGGER_LEVELS.inspect})" unless POSSIBLE_LOGGER_LEVELS.include?(logger_level)
|
82
|
+
|
83
83
|
utils.logger.level = logger_level
|
84
84
|
utils.logger.progname = name
|
85
85
|
end
|
data/lib/archfiend/cli.rb
CHANGED
@@ -1,4 +1,13 @@
|
|
1
1
|
require 'thor'
|
2
|
+
require 'pathname'
|
3
|
+
require 'forwardable'
|
4
|
+
require 'archfiend/version'
|
5
|
+
require 'archfiend/generators/daemon'
|
6
|
+
require 'archfiend/generators/options'
|
7
|
+
require 'archfiend/generators/extensions'
|
8
|
+
require 'archfiend/generators/utils'
|
9
|
+
require 'archfiend/core_ext/string/camelize'
|
10
|
+
require 'archfiend/core_ext/string/underscore'
|
2
11
|
|
3
12
|
module Archfiend
|
4
13
|
class CLI < Thor
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Archfiend
|
2
|
+
module String
|
3
|
+
module Camelize
|
4
|
+
# rubocop:disable Style/PerlBackrefs
|
5
|
+
# @return [String] String in the camelized format, first letter capital
|
6
|
+
def camelize
|
7
|
+
string = sub(/^[a-z\d]*/, &:capitalize)
|
8
|
+
string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{$2.capitalize}" }
|
9
|
+
string.gsub!('/'.freeze, '::'.freeze)
|
10
|
+
string
|
11
|
+
end
|
12
|
+
# rubocop:enable Style/PerlBackrefs
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
String.include(Archfiend::String::Camelize) unless ''.respond_to?(:camelize)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Archfiend
|
2
|
+
module String
|
3
|
+
module Underscore
|
4
|
+
# @return [String] String in the lowercase underscore format
|
5
|
+
def underscore
|
6
|
+
return self unless /[A-Z-]|::/.match?(self)
|
7
|
+
|
8
|
+
word = gsub('::'.freeze, '/'.freeze)
|
9
|
+
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2'.freeze)
|
10
|
+
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2'.freeze)
|
11
|
+
word.tr!('-'.freeze, '_'.freeze)
|
12
|
+
word.downcase!
|
13
|
+
word
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
String.include(Archfiend::String::Underscore) unless ''.respond_to?(:underscore)
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Archfiend
|
2
|
+
class Daemon
|
3
|
+
DEV_NULL = '/dev/null'.freeze
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def daemonize(pid_file:, log_file:, app_name:, app_env:)
|
7
|
+
Process.daemon(nil, true) # Don't close descriptors
|
8
|
+
handle_pid_file(pid_file)
|
9
|
+
close_io
|
10
|
+
redirect_std_io(log_file)
|
11
|
+
set_process_title(app_name, app_env)
|
12
|
+
srand
|
13
|
+
end
|
14
|
+
|
15
|
+
def set_process_title(app_name, app_env)
|
16
|
+
Process.setproctitle "#{app_name} (#{app_env})"
|
17
|
+
end
|
18
|
+
|
19
|
+
def handle_pid_file(pid_file)
|
20
|
+
if File.exist?(pid_file)
|
21
|
+
msg = "Pid file #{pid_file} already exists, the daemon is already running or " \
|
22
|
+
"didn't shut down properly. \nRemove the pid file and try again."
|
23
|
+
Process.abort(msg)
|
24
|
+
end
|
25
|
+
|
26
|
+
daemon_pid = Process.pid
|
27
|
+
begin
|
28
|
+
File.open(pid_file, 'w') { |f| f.puts daemon_pid }
|
29
|
+
rescue
|
30
|
+
msg = "Pid file creation failed, no permissions to write to #{pid_file}."
|
31
|
+
Process.abort(msg)
|
32
|
+
end
|
33
|
+
at_exit do
|
34
|
+
next unless Process.pid == daemon_pid
|
35
|
+
|
36
|
+
begin
|
37
|
+
File.unlink(pid_file)
|
38
|
+
rescue
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def redirect_std_io(log_file)
|
45
|
+
redirect_stdin
|
46
|
+
redirect_stdout(log_file)
|
47
|
+
redirect_stderr
|
48
|
+
end
|
49
|
+
|
50
|
+
def close_io
|
51
|
+
ObjectSpace.each_object(IO) do |io|
|
52
|
+
next if [$stdin, $stdout, $stderr].include?(io)
|
53
|
+
|
54
|
+
begin
|
55
|
+
io.close
|
56
|
+
rescue
|
57
|
+
nil
|
58
|
+
end
|
59
|
+
end
|
60
|
+
3.upto(8192) do |i|
|
61
|
+
begin
|
62
|
+
IO.for_fd(i).close
|
63
|
+
rescue
|
64
|
+
nil
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def redirect_stdin
|
72
|
+
$stdin.reopen DEV_NULL
|
73
|
+
rescue Exception # rubocop:disable Lint/RescueException
|
74
|
+
Process.abort('Failed to redirect stdin to dev null')
|
75
|
+
end
|
76
|
+
|
77
|
+
def redirect_stdout(logfile_name)
|
78
|
+
$stdout.reopen logfile_name, 'a'
|
79
|
+
File.chmod(0o644, logfile_name)
|
80
|
+
$stdout.sync = true
|
81
|
+
end
|
82
|
+
|
83
|
+
def redirect_stderr
|
84
|
+
$stderr.reopen $stdout
|
85
|
+
$stderr.sync = true
|
86
|
+
rescue ::Exception # rubocop:disable Lint/RescueException
|
87
|
+
Process.abort('Failed to redirect stderr to stdout')
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'active_support/inflector'
|
2
1
|
require 'thor'
|
3
2
|
|
4
3
|
module Archfiend
|
@@ -129,7 +128,13 @@ module Archfiend
|
|
129
128
|
end
|
130
129
|
|
131
130
|
def bundle_install
|
132
|
-
Bundler
|
131
|
+
if defined? Bundler
|
132
|
+
Bundler.with_clean_env do
|
133
|
+
inside daemon_name do
|
134
|
+
run 'bundle install'
|
135
|
+
end
|
136
|
+
end
|
137
|
+
else
|
133
138
|
inside daemon_name do
|
134
139
|
run 'bundle install'
|
135
140
|
end
|
@@ -1,18 +1,19 @@
|
|
1
1
|
require File.expand_path('application', __dir__)
|
2
2
|
|
3
|
+
base_dir = File.join(File.expand_path(__dir__), '..')
|
3
4
|
daemon_opts = {
|
4
|
-
app_name: '<%=
|
5
|
-
|
6
|
-
|
5
|
+
app_name: '<%= camelized_daemon_name %>',
|
6
|
+
app_env: <%= camelized_daemon_name %>.app.env,
|
7
|
+
log_file: File.join(base_dir, 'log', "#{<%= camelized_daemon_name %>.app.env}.log"),
|
8
|
+
pid_file: File.join(base_dir, '<%= daemon_name %>.pid')
|
7
9
|
}
|
8
10
|
|
9
|
-
#
|
11
|
+
# Close all file descriptors and prepare the app for the fork.
|
10
12
|
# Make sure new code doesn't rely on connections / logs etc opened before this call
|
11
|
-
|
13
|
+
Archfiend::Daemon.daemonize(**daemon_opts)
|
12
14
|
|
13
15
|
# Sets up Settings and many more
|
14
16
|
<%= camelized_daemon_name %>.app.setup
|
15
|
-
Process.setproctitle "#{Settings.app_name} (#{<%= camelized_daemon_name %>.app.env})"
|
16
17
|
|
17
18
|
# Runs the actual application
|
18
19
|
<%= camelized_daemon_name %>.app.run
|
@@ -60,6 +60,7 @@ module Archfiend
|
|
60
60
|
def generator_extensions
|
61
61
|
@generator_extensions ||= @extensions.map do |extension_module|
|
62
62
|
next unless extension_module.const_defined?(generator_extensions_class_name)
|
63
|
+
|
63
64
|
extension_klass = extension_module.const_get(generator_extensions_class_name)
|
64
65
|
next if extension_klass.respond_to?(:target_generator_name) && extension_klass.target_generator_name != @generator_name
|
65
66
|
|
data/lib/archfiend/logging.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
require 'logger'
|
2
|
-
require 'oj'
|
3
2
|
|
4
3
|
module Archfiend
|
5
4
|
class Logging
|
6
5
|
class << self
|
6
|
+
DEFAULT_FORMATTERS = {
|
7
|
+
file: 'JSONFormatter',
|
8
|
+
stdout: 'DefaultFormatter'
|
9
|
+
}.freeze
|
10
|
+
|
7
11
|
# @param environment [String|Symbol] Current running environment, ex. :development
|
8
12
|
# @param log_directory [String,Pathname] Directory in which the logfile is supposed to live
|
9
13
|
# @param quiet [Boolean] Whether the STDOUT development output should be suppressed
|
@@ -21,7 +25,7 @@ module Archfiend
|
|
21
25
|
def file_logger(environment, log_directory)
|
22
26
|
log_name = File.join(log_directory, "#{environment}.log")
|
23
27
|
file_logger = Logger.new(log_name, 'daily')
|
24
|
-
file_logger.formatter =
|
28
|
+
file_logger.formatter = formatter_from_settings(:file)
|
25
29
|
file_logger
|
26
30
|
end
|
27
31
|
|
@@ -30,9 +34,30 @@ module Archfiend
|
|
30
34
|
stdout_io.sync = true
|
31
35
|
stdout_logger = Logger.new(stdout_io)
|
32
36
|
|
33
|
-
stdout_logger.formatter =
|
37
|
+
stdout_logger.formatter = formatter_from_settings(:stdout)
|
34
38
|
stdout_logger
|
35
39
|
end
|
40
|
+
|
41
|
+
# @param type [Symbol] :file or :stdout
|
42
|
+
# @return [Logging::BaseFormatter] a formatter instance
|
43
|
+
def formatter_from_settings(type)
|
44
|
+
formatter_name = Settings.logger.dig(:formatter, type) || DEFAULT_FORMATTERS.fetch(type)
|
45
|
+
|
46
|
+
instantiate_formatter(formatter_name)
|
47
|
+
end
|
48
|
+
|
49
|
+
def instantiate_formatter(name)
|
50
|
+
return Archfiend::Logging.const_get(name).new if Archfiend::Logging.const_defined?(name)
|
51
|
+
|
52
|
+
possible_formatter_source = File.join('logging', name.underscore)
|
53
|
+
require_relative(possible_formatter_source)
|
54
|
+
|
55
|
+
Archfiend::Logging.const_get(name).new
|
56
|
+
rescue StandardError, LoadError => e
|
57
|
+
puts "Unable to load log formatter #{name.inspect}."
|
58
|
+
puts "\nException: #{e.message}"
|
59
|
+
exit 1
|
60
|
+
end
|
36
61
|
end
|
37
62
|
end
|
38
63
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Archfiend
|
2
2
|
class SubprocessLoop
|
3
|
-
extend Forwardable
|
3
|
+
extend ::Forwardable
|
4
4
|
include SharedLoop::Runnable
|
5
5
|
|
6
6
|
EXCEPTION_DELAY = 1 # Seconds to sleep for after rescuing recoverable exception
|
@@ -33,6 +33,7 @@ module Archfiend
|
|
33
33
|
|
34
34
|
def kill_all
|
35
35
|
return if !@subprocess_pids || @subprocess_pids.empty?
|
36
|
+
|
36
37
|
@subprocess_pids.each do |spid|
|
37
38
|
begin
|
38
39
|
Process.kill('TERM', spid)
|
data/lib/archfiend/version.rb
CHANGED
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Checks
|
4
|
+
class Footprint
|
5
|
+
def check(name, require_string, max_rss, max_ms)
|
6
|
+
puts "Checking footprint of #{name}"
|
7
|
+
|
8
|
+
summary_entry = footprint_json(require_string).find { |entry| entry['name'] == require_string }
|
9
|
+
unless summary_entry
|
10
|
+
puts "Failed finding the summary entry of #{require_string} in #{footprint_json.inspect}"
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
|
14
|
+
check_rss(name, summary_entry, max_rss)
|
15
|
+
check_time(name, summary_entry, max_ms)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def check_rss(name, entry, max)
|
21
|
+
puts "Archfiend #{name} RSS #{entry['rss']['mean']}"
|
22
|
+
return if entry['rss']['mean'] < max
|
23
|
+
|
24
|
+
puts "Exceeds maximal allowed #{max}"
|
25
|
+
exit 1
|
26
|
+
end
|
27
|
+
|
28
|
+
def check_time(name, entry, max)
|
29
|
+
puts "Archfiend #{name} require time #{entry['time']['mean']}ms"
|
30
|
+
return if entry['time']['mean'] < max
|
31
|
+
|
32
|
+
puts "Exceeds maximal allowed #{max}"
|
33
|
+
exit 1
|
34
|
+
end
|
35
|
+
|
36
|
+
def run_checker(require_string)
|
37
|
+
`RUBYLIB=./lib analyze_requires -r -f json -n 100 archfiend #{require_string}`
|
38
|
+
end
|
39
|
+
|
40
|
+
def footprint_json(require_string)
|
41
|
+
JSON.parse(run_checker(require_string))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/scripts/travis/install
CHANGED
data/scripts/travis/script
CHANGED
@@ -6,6 +6,12 @@
|
|
6
6
|
require 'pathname'
|
7
7
|
require 'fileutils'
|
8
8
|
|
9
|
+
require_relative 'checks/footprint'
|
10
|
+
|
11
|
+
MAX_RSS = 10_000
|
12
|
+
MAX_TIME = 100
|
13
|
+
MAX_CLI_TIME = 350
|
14
|
+
|
9
15
|
archfiend_root = Pathname.new File.expand_path(File.join('..', '..'), __dir__)
|
10
16
|
|
11
17
|
def system!(*args)
|
@@ -15,12 +21,21 @@ end
|
|
15
21
|
system!('BUNDLE_GEMFILE=Gemfile bundle exec rubocop')
|
16
22
|
system!('BUNDLE_GEMFILE=Gemfile bundle exec rspec')
|
17
23
|
|
18
|
-
|
24
|
+
footprint_checker = Checks::Footprint.new
|
25
|
+
footprint_checker.check('RunTime', './lib/archfiend', MAX_RSS, MAX_TIME)
|
26
|
+
footprint_checker.check('CLI', './lib/archfiend/cli', MAX_RSS, MAX_CLI_TIME)
|
19
27
|
|
28
|
+
system!('mkdir testing')
|
20
29
|
FileUtils.chdir(archfiend_root.join('testing')) do
|
21
30
|
system!('bundle exec archfiend new foo_bar')
|
22
31
|
end
|
23
32
|
|
33
|
+
FileUtils.chdir(archfiend_root.join('testing', 'foo_bar')) do
|
34
|
+
system!(%(sed -i s/.*''archfiend''.*// Gemfile)) # Remove the existing archfiend entry
|
35
|
+
File.open('Gemfile', 'a') { |f| f.puts "gem 'archfiend', path: '../..'" } # Use the local gem
|
36
|
+
system!('bundle install')
|
37
|
+
end
|
38
|
+
|
24
39
|
database_yml = '
|
25
40
|
test:
|
26
41
|
adapter: postgresql
|
metadata
CHANGED
@@ -1,43 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: archfiend
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Maciek Dubiński
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-01-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: activesupport
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: activerecord
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
30
16
|
requirements:
|
31
|
-
- - "
|
17
|
+
- - "~>"
|
32
18
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
19
|
+
version: '5'
|
34
20
|
type: :development
|
35
21
|
prerelease: false
|
36
22
|
version_requirements: !ruby/object:Gem::Requirement
|
37
23
|
requirements:
|
38
|
-
- - "
|
24
|
+
- - "~>"
|
39
25
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
26
|
+
version: '5'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: bundler
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -56,30 +42,30 @@ dependencies:
|
|
56
42
|
name: config
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
58
44
|
requirements:
|
59
|
-
- - "
|
45
|
+
- - "~>"
|
60
46
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
47
|
+
version: '1.7'
|
62
48
|
type: :development
|
63
49
|
prerelease: false
|
64
50
|
version_requirements: !ruby/object:Gem::Requirement
|
65
51
|
requirements:
|
66
|
-
- - "
|
52
|
+
- - "~>"
|
67
53
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
54
|
+
version: '1.7'
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
56
|
name: oj
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
72
58
|
requirements:
|
73
|
-
- - "
|
59
|
+
- - "~>"
|
74
60
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
61
|
+
version: '3.6'
|
76
62
|
type: :runtime
|
77
63
|
prerelease: false
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
79
65
|
requirements:
|
80
|
-
- - "
|
66
|
+
- - "~>"
|
81
67
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
68
|
+
version: '3.6'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
70
|
name: pg
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -98,16 +84,16 @@ dependencies:
|
|
98
84
|
name: pry
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
100
86
|
requirements:
|
101
|
-
- - "
|
87
|
+
- - "~>"
|
102
88
|
- !ruby/object:Gem::Version
|
103
|
-
version: '0'
|
104
|
-
type: :
|
89
|
+
version: '0.11'
|
90
|
+
type: :development
|
105
91
|
prerelease: false
|
106
92
|
version_requirements: !ruby/object:Gem::Requirement
|
107
93
|
requirements:
|
108
|
-
- - "
|
94
|
+
- - "~>"
|
109
95
|
- !ruby/object:Gem::Version
|
110
|
-
version: '0'
|
96
|
+
version: '0.11'
|
111
97
|
- !ruby/object:Gem::Dependency
|
112
98
|
name: rake
|
113
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -140,44 +126,44 @@ dependencies:
|
|
140
126
|
name: rubocop
|
141
127
|
requirement: !ruby/object:Gem::Requirement
|
142
128
|
requirements:
|
143
|
-
- - "
|
129
|
+
- - "~>"
|
144
130
|
- !ruby/object:Gem::Version
|
145
|
-
version: '0'
|
131
|
+
version: '0.59'
|
146
132
|
type: :development
|
147
133
|
prerelease: false
|
148
134
|
version_requirements: !ruby/object:Gem::Requirement
|
149
135
|
requirements:
|
150
|
-
- - "
|
136
|
+
- - "~>"
|
151
137
|
- !ruby/object:Gem::Version
|
152
|
-
version: '0'
|
138
|
+
version: '0.59'
|
153
139
|
- !ruby/object:Gem::Dependency
|
154
140
|
name: rubocop-rspec
|
155
141
|
requirement: !ruby/object:Gem::Requirement
|
156
142
|
requirements:
|
157
|
-
- - "
|
143
|
+
- - "~>"
|
158
144
|
- !ruby/object:Gem::Version
|
159
|
-
version: '
|
145
|
+
version: '1.30'
|
160
146
|
type: :development
|
161
147
|
prerelease: false
|
162
148
|
version_requirements: !ruby/object:Gem::Requirement
|
163
149
|
requirements:
|
164
|
-
- - "
|
150
|
+
- - "~>"
|
165
151
|
- !ruby/object:Gem::Version
|
166
|
-
version: '
|
152
|
+
version: '1.30'
|
167
153
|
- !ruby/object:Gem::Dependency
|
168
154
|
name: thor
|
169
155
|
requirement: !ruby/object:Gem::Requirement
|
170
156
|
requirements:
|
171
|
-
- - "
|
157
|
+
- - "~>"
|
172
158
|
- !ruby/object:Gem::Version
|
173
|
-
version: '0'
|
159
|
+
version: '0.20'
|
174
160
|
type: :runtime
|
175
161
|
prerelease: false
|
176
162
|
version_requirements: !ruby/object:Gem::Requirement
|
177
163
|
requirements:
|
178
|
-
- - "
|
164
|
+
- - "~>"
|
179
165
|
- !ruby/object:Gem::Version
|
180
|
-
version: '0'
|
166
|
+
version: '0.20'
|
181
167
|
description: A tool to simplify creation and development of Ruby daemons.
|
182
168
|
email:
|
183
169
|
- maciek@dubinski.net
|
@@ -206,6 +192,9 @@ files:
|
|
206
192
|
- lib/archfiend.rb
|
207
193
|
- lib/archfiend/application.rb
|
208
194
|
- lib/archfiend/cli.rb
|
195
|
+
- lib/archfiend/core_ext/string/camelize.rb
|
196
|
+
- lib/archfiend/core_ext/string/underscore.rb
|
197
|
+
- lib/archfiend/daemon.rb
|
209
198
|
- lib/archfiend/generators/daemon.rb
|
210
199
|
- lib/archfiend/generators/daemon/templates/.rspec
|
211
200
|
- lib/archfiend/generators/daemon/templates/.rubocop.yml
|
@@ -251,6 +240,7 @@ files:
|
|
251
240
|
- lib/archfiend/subprocess_loop.rb
|
252
241
|
- lib/archfiend/thread_loop.rb
|
253
242
|
- lib/archfiend/version.rb
|
243
|
+
- scripts/travis/checks/footprint.rb
|
254
244
|
- scripts/travis/install
|
255
245
|
- scripts/travis/script
|
256
246
|
homepage: https://github.com/toptal/archfiend
|