archfiend 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Build Status](https://travis-ci.com/toptal/archfiend.svg?branch=master)](https://travis-ci.com/toptal/archfiend)
|
7
|
+
[![Gem Version](https://badge.fury.io/rb/archfiend.svg)](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
|