pakyow-core 0.11.3 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +0 -0
- data/LICENSE +4 -0
- data/{pakyow-core/README.md → README.md} +3 -4
- data/commands/pakyow +13 -0
- data/lib/pakyow/app/connection/behavior/session.rb +33 -0
- data/lib/pakyow/app/connection/behavior/values.rb +42 -0
- data/lib/pakyow/app/connection/behavior/verifier.rb +34 -0
- data/lib/pakyow/app/connection/session/abstract.rb +24 -0
- data/lib/pakyow/app/connection/session/cookie.rb +56 -0
- data/lib/pakyow/app/connection.rb +57 -0
- data/lib/pakyow/app.rb +219 -0
- data/lib/pakyow/behavior/aspects.rb +45 -0
- data/lib/pakyow/behavior/config.rb +72 -0
- data/lib/pakyow/behavior/endpoints.rb +41 -0
- data/lib/pakyow/behavior/frameworks.rb +45 -0
- data/lib/pakyow/behavior/helpers.rb +107 -0
- data/lib/pakyow/behavior/initializers.rb +19 -0
- data/lib/pakyow/behavior/isolating.rb +69 -0
- data/lib/pakyow/behavior/operations.rb +46 -0
- data/lib/pakyow/behavior/pipeline.rb +58 -0
- data/lib/pakyow/behavior/plugins.rb +148 -0
- data/lib/pakyow/behavior/rescuing.rb +51 -0
- data/lib/pakyow/behavior/restarting.rb +68 -0
- data/lib/pakyow/behavior/sessions.rb +34 -0
- data/lib/pakyow/behavior/verification.rb +47 -0
- data/lib/pakyow/cli.rb +199 -0
- data/lib/pakyow/connection/multipart_input.rb +24 -0
- data/lib/pakyow/connection/multipart_parser.rb +112 -0
- data/lib/pakyow/connection/params.rb +29 -0
- data/lib/pakyow/connection/query_parser.rb +174 -0
- data/lib/pakyow/connection/statuses.rb +119 -0
- data/lib/pakyow/connection.rb +568 -0
- data/lib/pakyow/endpoints.rb +94 -0
- data/lib/pakyow/environment/actions/dispatch.rb +37 -0
- data/lib/pakyow/environment/actions/input_parser.rb +21 -0
- data/lib/pakyow/environment/actions/logger.rb +33 -0
- data/lib/pakyow/environment/actions/normalizer.rb +73 -0
- data/lib/pakyow/environment/behavior/config.rb +166 -0
- data/lib/pakyow/environment/behavior/initializers.rb +21 -0
- data/lib/pakyow/environment/behavior/input_parsing.rb +54 -0
- data/lib/pakyow/environment/behavior/plugins.rb +23 -0
- data/lib/pakyow/environment/behavior/restarting.rb +54 -0
- data/lib/pakyow/environment/behavior/running.rb +129 -0
- data/lib/pakyow/environment/behavior/silencing.rb +23 -0
- data/lib/pakyow/environment/behavior/timezone.rb +21 -0
- data/lib/pakyow/environment/behavior/watching.rb +75 -0
- data/lib/pakyow/environment.rb +381 -0
- data/lib/pakyow/error.rb +273 -0
- data/lib/pakyow/errors.rb +97 -0
- data/lib/pakyow/framework.rb +39 -0
- data/lib/pakyow/generator.rb +138 -0
- data/lib/pakyow/generators/project/default/%dot%env.erb +1 -0
- data/lib/pakyow/generators/project/default/%dot%gitignore +11 -0
- data/lib/pakyow/generators/project/default/%dot%ruby-version.erb +1 -0
- data/lib/pakyow/generators/project/default/Gemfile.erb +28 -0
- data/lib/pakyow/generators/project/default/README.md +14 -0
- data/lib/pakyow/generators/project/default/config/application.rb.erb +17 -0
- data/lib/pakyow/generators/project/default/config/environment.rb +11 -0
- data/lib/pakyow/generators/project/default/config/initializers/application/keep +0 -0
- data/lib/pakyow/generators/project/default/config/initializers/environment/keep +0 -0
- data/lib/pakyow/generators/project/default/database/keep +0 -0
- data/lib/pakyow/generators/project/default/frontend/assets/images/keep +0 -0
- data/lib/pakyow/generators/project/default/frontend/assets/packs/keep +0 -0
- data/lib/pakyow/generators/project/default/frontend/assets/styles/keep +0 -0
- data/lib/pakyow/generators/project/default/frontend/includes/keep +0 -0
- data/lib/pakyow/generators/project/default/frontend/layouts/default.html.erb +19 -0
- data/lib/pakyow/generators/project/default/frontend/pages/keep +0 -0
- data/lib/pakyow/generators/project/default/public/favicon.ico +0 -0
- data/lib/pakyow/generators/project/default/public/robots.txt +1 -0
- data/lib/pakyow/generators/project.rb +29 -0
- data/lib/pakyow/helpers/app.rb +28 -0
- data/lib/pakyow/helpers/connection.rb +45 -0
- data/lib/pakyow/info.rb +26 -0
- data/lib/pakyow/integrations/bootsnap.rb +18 -0
- data/lib/pakyow/integrations/bundler/require.rb +7 -0
- data/lib/pakyow/integrations/bundler/setup.rb +7 -0
- data/lib/pakyow/integrations/dotenv.rb +9 -0
- data/lib/pakyow/loader.rb +31 -0
- data/lib/pakyow/logger/colorizer.rb +38 -0
- data/lib/pakyow/logger/destination.rb +17 -0
- data/lib/pakyow/logger/formatter.rb +22 -0
- data/lib/pakyow/logger/formatters/human.rb +101 -0
- data/lib/pakyow/logger/formatters/json.rb +99 -0
- data/lib/pakyow/logger/formatters/logfmt.rb +50 -0
- data/lib/pakyow/logger/multiplexed.rb +19 -0
- data/lib/pakyow/logger/thread_local.rb +29 -0
- data/lib/pakyow/logger/timekeeper.rb +64 -0
- data/lib/pakyow/logger.rb +125 -0
- data/lib/pakyow/operation.rb +71 -0
- data/lib/pakyow/plugin/helper_caller.rb +20 -0
- data/lib/pakyow/plugin/lookup.rb +33 -0
- data/lib/pakyow/plugin/state.rb +68 -0
- data/lib/pakyow/plugin.rb +367 -0
- data/lib/pakyow/process_manager.rb +53 -0
- data/lib/pakyow/processes/proxy.rb +67 -0
- data/lib/pakyow/processes/server.rb +32 -0
- data/lib/pakyow/rack/compatibility.rb +68 -0
- data/lib/pakyow/task.rb +315 -0
- data/lib/pakyow/tasks/boot.rake +21 -0
- data/lib/pakyow/tasks/create.rake +32 -0
- data/lib/pakyow/tasks/help.rake +17 -0
- data/lib/pakyow/tasks/info/endpoints.rake +72 -0
- data/lib/pakyow/tasks/info.rake +31 -0
- data/lib/pakyow/tasks/irb.rake +11 -0
- data/lib/pakyow/tasks/prelaunch.rake +37 -0
- data/lib/pakyow/types.rb +32 -0
- data/lib/pakyow/validations/acceptance.rb +37 -0
- data/lib/pakyow/validations/email.rb +28 -0
- data/lib/pakyow/validations/inline.rb +32 -0
- data/lib/pakyow/validations/length.rb +44 -0
- data/lib/pakyow/validations/presence.rb +41 -0
- data/lib/pakyow/validations.rb +8 -0
- data/lib/pakyow/validator.rb +81 -0
- data/lib/pakyow/verifier.rb +177 -0
- data/lib/pakyow.rb +5 -0
- metadata +267 -65
- data/pakyow-core/CHANGELOG.md +0 -128
- data/pakyow-core/LICENSE +0 -20
- data/pakyow-core/lib/pakyow/core/app.rb +0 -82
- data/pakyow-core/lib/pakyow/core/app_context.rb +0 -10
- data/pakyow-core/lib/pakyow/core/base.rb +0 -61
- data/pakyow-core/lib/pakyow/core/call_context.rb +0 -171
- data/pakyow-core/lib/pakyow/core/config/app.rb +0 -49
- data/pakyow-core/lib/pakyow/core/config/cookies.rb +0 -4
- data/pakyow-core/lib/pakyow/core/config/logger.rb +0 -34
- data/pakyow-core/lib/pakyow/core/config/reloader.rb +0 -10
- data/pakyow-core/lib/pakyow/core/config/server.rb +0 -10
- data/pakyow-core/lib/pakyow/core/config/session.rb +0 -41
- data/pakyow-core/lib/pakyow/core/config.rb +0 -95
- data/pakyow-core/lib/pakyow/core/errors.rb +0 -16
- data/pakyow-core/lib/pakyow/core/helpers/configuring.rb +0 -142
- data/pakyow-core/lib/pakyow/core/helpers/hooks.rb +0 -106
- data/pakyow-core/lib/pakyow/core/helpers/running.rb +0 -124
- data/pakyow-core/lib/pakyow/core/helpers.rb +0 -61
- data/pakyow-core/lib/pakyow/core/loader.rb +0 -32
- data/pakyow-core/lib/pakyow/core/middleware/logger.rb +0 -146
- data/pakyow-core/lib/pakyow/core/middleware/override.rb +0 -3
- data/pakyow-core/lib/pakyow/core/middleware/reloader.rb +0 -23
- data/pakyow-core/lib/pakyow/core/middleware/req_path_normalizer.rb +0 -49
- data/pakyow-core/lib/pakyow/core/middleware/session.rb +0 -5
- data/pakyow-core/lib/pakyow/core/middleware/static.rb +0 -76
- data/pakyow-core/lib/pakyow/core/multilog.rb +0 -19
- data/pakyow-core/lib/pakyow/core/request.rb +0 -119
- data/pakyow-core/lib/pakyow/core/response.rb +0 -135
- data/pakyow-core/lib/pakyow/core/route_eval.rb +0 -254
- data/pakyow-core/lib/pakyow/core/route_expansion_eval.rb +0 -115
- data/pakyow-core/lib/pakyow/core/route_lookup.rb +0 -41
- data/pakyow-core/lib/pakyow/core/route_merger.rb +0 -76
- data/pakyow-core/lib/pakyow/core/route_module.rb +0 -21
- data/pakyow-core/lib/pakyow/core/route_set.rb +0 -74
- data/pakyow-core/lib/pakyow/core/route_template_defaults.rb +0 -43
- data/pakyow-core/lib/pakyow/core/route_template_eval.rb +0 -72
- data/pakyow-core/lib/pakyow/core/router.rb +0 -181
- data/pakyow-core/lib/pakyow/core.rb +0 -8
- data/pakyow-core/lib/pakyow-core.rb +0 -1
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pakyow
|
4
|
+
module Actions
|
5
|
+
# Sets up a connection logger and logs the prologue/epilogue.
|
6
|
+
#
|
7
|
+
class Logger
|
8
|
+
def call(connection, &block)
|
9
|
+
if silence?(connection)
|
10
|
+
connection.logger.silence do
|
11
|
+
call_with_logging(connection, &block)
|
12
|
+
end
|
13
|
+
else
|
14
|
+
call_with_logging(connection, &block)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def call_with_logging(connection)
|
21
|
+
connection.logger.prologue(connection)
|
22
|
+
yield
|
23
|
+
connection.logger.epilogue(connection)
|
24
|
+
end
|
25
|
+
|
26
|
+
def silence?(connection)
|
27
|
+
Pakyow.silencers.any? { |silencer|
|
28
|
+
silencer.call(connection)
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pakyow/support/core_refinements/string/normalization"
|
4
|
+
|
5
|
+
module Pakyow
|
6
|
+
module Actions
|
7
|
+
# Normalizes request uris, issuing a 301 redirect to the normalized uri.
|
8
|
+
#
|
9
|
+
class Normalizer
|
10
|
+
using Support::Refinements::String::Normalization
|
11
|
+
|
12
|
+
def call(connection)
|
13
|
+
if strict_www? && require_www? && !www?(connection) && !subdomain?(connection)
|
14
|
+
redirect!(connection, File.join(add_www(connection), connection.path))
|
15
|
+
elsif strict_www? && !require_www? && www?(connection)
|
16
|
+
redirect!(connection, File.join(remove_www(connection), connection.path))
|
17
|
+
elsif strict_path? && slash?(connection)
|
18
|
+
redirect!(connection, String.normalize_path(connection.path))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def redirect!(connection, location)
|
25
|
+
connection.status = 301
|
26
|
+
connection.set_header("Location", location)
|
27
|
+
connection.halt
|
28
|
+
end
|
29
|
+
|
30
|
+
def add_www(connection)
|
31
|
+
"www.#{connection.authority}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def remove_www(connection)
|
35
|
+
connection.authority.split(".", 2)[1]
|
36
|
+
end
|
37
|
+
|
38
|
+
def slash?(connection)
|
39
|
+
double_slash?(connection) || tail_slash?(connection)
|
40
|
+
end
|
41
|
+
|
42
|
+
def double_slash?(connection)
|
43
|
+
connection.path.include?("//")
|
44
|
+
end
|
45
|
+
|
46
|
+
TAIL_SLASH_REGEX = /(.)+(\/)+$/
|
47
|
+
|
48
|
+
def tail_slash?(connection)
|
49
|
+
!(TAIL_SLASH_REGEX =~ connection.path).nil?
|
50
|
+
end
|
51
|
+
|
52
|
+
def subdomain?(connection)
|
53
|
+
connection.host.count(".") > 1
|
54
|
+
end
|
55
|
+
|
56
|
+
def www?(connection)
|
57
|
+
connection.subdomain == "www"
|
58
|
+
end
|
59
|
+
|
60
|
+
def strict_path?
|
61
|
+
Pakyow.config.normalizer.strict_path == true
|
62
|
+
end
|
63
|
+
|
64
|
+
def strict_www?
|
65
|
+
Pakyow.config.normalizer.strict_www == true
|
66
|
+
end
|
67
|
+
|
68
|
+
def require_www?
|
69
|
+
Pakyow.config.normalizer.require_www == true
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pakyow/support/extension"
|
4
|
+
|
5
|
+
require "pakyow/logger/formatters/human"
|
6
|
+
require "pakyow/logger/formatters/logfmt"
|
7
|
+
|
8
|
+
module Pakyow
|
9
|
+
module Environment
|
10
|
+
module Behavior
|
11
|
+
module Config
|
12
|
+
extend Support::Extension
|
13
|
+
|
14
|
+
apply_extension do
|
15
|
+
setting :default_env, :development
|
16
|
+
setting :freeze_on_boot, true
|
17
|
+
setting :exit_on_boot_failure, true
|
18
|
+
setting :timezone, :utc
|
19
|
+
setting :connection_class do
|
20
|
+
require "pakyow/connection"
|
21
|
+
Connection
|
22
|
+
end
|
23
|
+
|
24
|
+
setting :root do
|
25
|
+
File.expand_path(".")
|
26
|
+
end
|
27
|
+
|
28
|
+
setting :lib do
|
29
|
+
File.join(config.root, "lib")
|
30
|
+
end
|
31
|
+
|
32
|
+
setting :environment_path do
|
33
|
+
File.join(config.root, "config/environment")
|
34
|
+
end
|
35
|
+
|
36
|
+
setting :loader_path do
|
37
|
+
File.join(config.root, "config/loader")
|
38
|
+
end
|
39
|
+
|
40
|
+
defaults :test do
|
41
|
+
setting :exit_on_boot_failure, false
|
42
|
+
end
|
43
|
+
|
44
|
+
configurable :server do
|
45
|
+
setting :host, "localhost"
|
46
|
+
setting :port, 3000
|
47
|
+
setting :count, 1
|
48
|
+
setting :proxy, true
|
49
|
+
|
50
|
+
defaults :production do
|
51
|
+
setting :proxy, false
|
52
|
+
|
53
|
+
setting :host do
|
54
|
+
ENV["HOST"] || "0.0.0.0"
|
55
|
+
end
|
56
|
+
|
57
|
+
setting :port do
|
58
|
+
ENV["PORT"] || 3000
|
59
|
+
end
|
60
|
+
|
61
|
+
setting :count do
|
62
|
+
ENV["WORKERS"] || 5
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
configurable :cli do
|
68
|
+
setting :repl do
|
69
|
+
require "irb"; IRB
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
configurable :logger do
|
74
|
+
setting :enabled, true
|
75
|
+
setting :sync, true
|
76
|
+
|
77
|
+
setting :level do
|
78
|
+
if config.logger.enabled
|
79
|
+
:debug
|
80
|
+
else
|
81
|
+
:off
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
setting :formatter do
|
86
|
+
Logger::Formatters::Human
|
87
|
+
end
|
88
|
+
|
89
|
+
setting :destinations do
|
90
|
+
if config.logger.enabled
|
91
|
+
{ stdout: $stdout }
|
92
|
+
else
|
93
|
+
{}
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
defaults :test do
|
98
|
+
setting :enabled, false
|
99
|
+
end
|
100
|
+
|
101
|
+
defaults :production do
|
102
|
+
setting :level do
|
103
|
+
if config.logger.enabled
|
104
|
+
:info
|
105
|
+
else
|
106
|
+
:off
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
setting :formatter do
|
111
|
+
Logger::Formatters::Logfmt
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
defaults :ludicrous do
|
116
|
+
setting :enabled, false
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
configurable :normalizer do
|
121
|
+
setting :strict_path, true
|
122
|
+
setting :strict_www, false
|
123
|
+
setting :require_www, true
|
124
|
+
end
|
125
|
+
|
126
|
+
configurable :tasks do
|
127
|
+
setting :paths, ["./tasks", File.expand_path("../../../tasks", __FILE__)]
|
128
|
+
setting :prelaunch, []
|
129
|
+
end
|
130
|
+
|
131
|
+
configurable :redis do
|
132
|
+
configurable :connection do
|
133
|
+
setting :url do
|
134
|
+
ENV["REDIS_URL"] || "redis://127.0.0.1:6379"
|
135
|
+
end
|
136
|
+
|
137
|
+
setting :timeout, 5
|
138
|
+
setting :driver, nil
|
139
|
+
setting :id, nil
|
140
|
+
setting :tcp_keepalive, 5
|
141
|
+
setting :reconnect_attempts, 1
|
142
|
+
setting :inherit_socket, false
|
143
|
+
end
|
144
|
+
|
145
|
+
configurable :pool do
|
146
|
+
setting :size, 3
|
147
|
+
setting :timeout, 1
|
148
|
+
end
|
149
|
+
|
150
|
+
setting :key_prefix, "pw"
|
151
|
+
end
|
152
|
+
|
153
|
+
configurable :cookies do
|
154
|
+
setting :domain
|
155
|
+
setting :path, "/"
|
156
|
+
setting :max_age
|
157
|
+
setting :expires
|
158
|
+
setting :secure
|
159
|
+
setting :http_only
|
160
|
+
setting :same_site
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pakyow/support/extension"
|
4
|
+
|
5
|
+
module Pakyow
|
6
|
+
module Environment
|
7
|
+
module Behavior
|
8
|
+
module Initializers
|
9
|
+
extend Support::Extension
|
10
|
+
|
11
|
+
apply_extension do
|
12
|
+
on "configure" do
|
13
|
+
Dir.glob(File.join(Pakyow.config.root, "config/initializers/environment/**/*.rb")).each do |initializer|
|
14
|
+
require initializer
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
|
5
|
+
require "pakyow/support/extension"
|
6
|
+
require "pakyow/support/indifferentize"
|
7
|
+
|
8
|
+
require "pakyow/connection/query_parser"
|
9
|
+
require "pakyow/connection/multipart_parser"
|
10
|
+
|
11
|
+
module Pakyow
|
12
|
+
module Environment
|
13
|
+
module Behavior
|
14
|
+
module InputParsing
|
15
|
+
extend Support::Extension
|
16
|
+
using Support::Indifferentize
|
17
|
+
|
18
|
+
apply_extension do
|
19
|
+
class_state :input_parsers, default: {}
|
20
|
+
|
21
|
+
on "configure" do
|
22
|
+
Pakyow.parse_input "application/x-www-form-urlencoded" do |input, connection|
|
23
|
+
connection.params.parse(input.read)
|
24
|
+
end
|
25
|
+
|
26
|
+
Pakyow.parse_input "multipart/form-data" do |input, connection|
|
27
|
+
Connection::MultipartParser.new(
|
28
|
+
connection.params, boundary: connection.type_params[:boundary]
|
29
|
+
).parse(input)
|
30
|
+
end
|
31
|
+
|
32
|
+
Pakyow.parse_input "application/json" do |input, connection|
|
33
|
+
values = JSON.parse(input.read)
|
34
|
+
|
35
|
+
if values.is_a?(Hash)
|
36
|
+
values.deep_indifferentize.each do |key, value|
|
37
|
+
connection.params.add(key, value)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
values
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class_methods do
|
47
|
+
def parse_input(type, &block)
|
48
|
+
@input_parsers[type] = block
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pakyow/support/extension"
|
4
|
+
|
5
|
+
module Pakyow
|
6
|
+
module Environment
|
7
|
+
module Behavior
|
8
|
+
module Plugins
|
9
|
+
extend Support::Extension
|
10
|
+
|
11
|
+
apply_extension do
|
12
|
+
class_state :plugins, default: {}
|
13
|
+
end
|
14
|
+
|
15
|
+
class_methods do
|
16
|
+
def register_plugin(plugin_name, plugin_module)
|
17
|
+
@plugins[plugin_name] = plugin_module
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pakyow/support/extension"
|
4
|
+
|
5
|
+
module Pakyow
|
6
|
+
module Environment
|
7
|
+
module Behavior
|
8
|
+
module Restarting
|
9
|
+
extend Support::Extension
|
10
|
+
|
11
|
+
apply_extension do
|
12
|
+
on "run" do
|
13
|
+
@respawn = false
|
14
|
+
|
15
|
+
# Other processes (e.g. apps) can touch this file to restart the server.
|
16
|
+
#
|
17
|
+
watch "./tmp/restart.txt" do
|
18
|
+
restart
|
19
|
+
end
|
20
|
+
|
21
|
+
# Automatically bundle.
|
22
|
+
#
|
23
|
+
watch "./Gemfile" do
|
24
|
+
Bundler.with_clean_env do
|
25
|
+
Support::CLI::Runner.new(message: "Bundling").run("bundle install")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Respawn when the bundle changes.
|
30
|
+
#
|
31
|
+
watch "./Gemfile.lock" do
|
32
|
+
respawn
|
33
|
+
end
|
34
|
+
|
35
|
+
# Respawn when something about the environment changes.
|
36
|
+
#
|
37
|
+
watch "#{Pakyow.config.environment_path}.rb" do
|
38
|
+
respawn
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class_methods do
|
44
|
+
def respawn
|
45
|
+
# Set the respawn flag and stop the process manager.
|
46
|
+
# Pakyow will check the flag and respawn from the main thread.
|
47
|
+
#
|
48
|
+
@respawn = true; @process_manager.stop
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "async/reactor"
|
4
|
+
require "async/io/shared_endpoint"
|
5
|
+
require "async/http/endpoint"
|
6
|
+
|
7
|
+
require "pakyow/support/extension"
|
8
|
+
|
9
|
+
require "pakyow/process_manager"
|
10
|
+
require "pakyow/processes/proxy"
|
11
|
+
require "pakyow/processes/server"
|
12
|
+
|
13
|
+
module Pakyow
|
14
|
+
module Environment
|
15
|
+
module Behavior
|
16
|
+
module Running
|
17
|
+
extend Support::Extension
|
18
|
+
|
19
|
+
apply_extension do
|
20
|
+
unfreezable :process_manager
|
21
|
+
|
22
|
+
class_state :processes, default: []
|
23
|
+
|
24
|
+
on "run" do
|
25
|
+
if config.server.proxy
|
26
|
+
# Find a port to run the environment on, start the proxy on the configured port.
|
27
|
+
#
|
28
|
+
port = Processes::Proxy.find_local_port
|
29
|
+
process :proxy, restartable: false do
|
30
|
+
Processes::Proxy.new(
|
31
|
+
host: config.server.host,
|
32
|
+
port: config.server.port,
|
33
|
+
proxy_port: port
|
34
|
+
).run
|
35
|
+
end
|
36
|
+
else
|
37
|
+
# Run the environment on the configured port.
|
38
|
+
#
|
39
|
+
port = config.server.port
|
40
|
+
end
|
41
|
+
|
42
|
+
endpoint = Async::HTTP::Endpoint.parse(
|
43
|
+
"http://#{config.server.host}:#{port}"
|
44
|
+
)
|
45
|
+
|
46
|
+
bound_endpoint = Async::Reactor.run {
|
47
|
+
Async::IO::SharedEndpoint.bound(endpoint)
|
48
|
+
}.wait
|
49
|
+
|
50
|
+
process :server, count: config.server.count do
|
51
|
+
Pakyow.config.server.port = port
|
52
|
+
|
53
|
+
Processes::Server.new(
|
54
|
+
protocol: endpoint.protocol,
|
55
|
+
scheme: endpoint.scheme,
|
56
|
+
endpoint: bound_endpoint
|
57
|
+
).run
|
58
|
+
end
|
59
|
+
|
60
|
+
unless config.server.proxy || ENV.key?("PW_RESPAWN")
|
61
|
+
Pakyow.logger << Processes::Server.running_text(
|
62
|
+
scheme: endpoint.scheme, host: config.server.host, port: port
|
63
|
+
)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class_methods do
|
69
|
+
def process(name, count: 1, restartable: true, &block)
|
70
|
+
@processes << {
|
71
|
+
name: name,
|
72
|
+
block: block,
|
73
|
+
count: count,
|
74
|
+
restartable: restartable
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
def run
|
79
|
+
performing :run do
|
80
|
+
@process_manager = @processes.each_with_object(ProcessManager.new) { |process, manager|
|
81
|
+
manager.add(process)
|
82
|
+
}
|
83
|
+
|
84
|
+
root_pid = Process.pid
|
85
|
+
|
86
|
+
at_exit do
|
87
|
+
if Process.pid == root_pid
|
88
|
+
shutdown
|
89
|
+
else
|
90
|
+
@apps.select { |app|
|
91
|
+
app.respond_to?(:shutdown)
|
92
|
+
}.each(&:shutdown)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
@process_manager.wait
|
98
|
+
|
99
|
+
if @respawn
|
100
|
+
# Replace the master process with a copy of itself.
|
101
|
+
#
|
102
|
+
exec "PW_RESPAWN=true #{$0} #{ARGV.join(" ")}"
|
103
|
+
end
|
104
|
+
rescue SignalException
|
105
|
+
exit
|
106
|
+
end
|
107
|
+
|
108
|
+
def shutdown
|
109
|
+
if $stdout.isatty
|
110
|
+
# Don't let ^C mess up our output.
|
111
|
+
#
|
112
|
+
puts
|
113
|
+
end
|
114
|
+
|
115
|
+
Pakyow.logger << "Goodbye"
|
116
|
+
|
117
|
+
performing :shutdown do
|
118
|
+
@process_manager.stop
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def restart
|
123
|
+
@process_manager.restart
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pakyow/support/extension"
|
4
|
+
|
5
|
+
module Pakyow
|
6
|
+
module Environment
|
7
|
+
module Behavior
|
8
|
+
module Silencing
|
9
|
+
extend Support::Extension
|
10
|
+
|
11
|
+
apply_extension do
|
12
|
+
class_state :silencers, default: []
|
13
|
+
end
|
14
|
+
|
15
|
+
class_methods do
|
16
|
+
def silence(&block)
|
17
|
+
@silencers << block
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pakyow/support/extension"
|
4
|
+
|
5
|
+
module Pakyow
|
6
|
+
module Environment
|
7
|
+
module Behavior
|
8
|
+
# Sets up the timezone for the environment.
|
9
|
+
#
|
10
|
+
module Timezone
|
11
|
+
extend Support::Extension
|
12
|
+
|
13
|
+
apply_extension do
|
14
|
+
after "configure" do
|
15
|
+
ENV["TZ"] = config.timezone.to_s
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "filewatcher"
|
4
|
+
|
5
|
+
require "pakyow/support/extension"
|
6
|
+
|
7
|
+
module Pakyow
|
8
|
+
module Environment
|
9
|
+
module Behavior
|
10
|
+
module Watching
|
11
|
+
extend Support::Extension
|
12
|
+
|
13
|
+
apply_extension do
|
14
|
+
class_state :on_change_matchers, default: {}
|
15
|
+
class_state :watched_paths, default: []
|
16
|
+
|
17
|
+
unfreezable :filewatcher, :filewatcher_thread
|
18
|
+
|
19
|
+
after "run" do
|
20
|
+
@filewatcher = Filewatcher.new(
|
21
|
+
@watched_paths.map { |path|
|
22
|
+
File.expand_path(path)
|
23
|
+
}
|
24
|
+
)
|
25
|
+
|
26
|
+
@filewatcher_thread = Thread.new do
|
27
|
+
@filewatcher.watch(&method(:watch_callback))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
on "shutdown" do
|
32
|
+
@filewatcher.stop
|
33
|
+
@filewatcher_thread.join
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class_methods do
|
38
|
+
# Register a callback to be called when a file changes.
|
39
|
+
#
|
40
|
+
def on_change(matcher, &block)
|
41
|
+
(@on_change_matchers[matcher] ||= []) << block
|
42
|
+
end
|
43
|
+
|
44
|
+
# Register one or more path for changes.
|
45
|
+
#
|
46
|
+
def watch(*paths, &block)
|
47
|
+
@watched_paths.concat(paths).uniq!
|
48
|
+
|
49
|
+
if block
|
50
|
+
paths.each do |path|
|
51
|
+
on_change(File.expand_path(path), &block)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# @api private
|
57
|
+
def change_callbacks(path)
|
58
|
+
@on_change_matchers.each_with_object([]) { |(matcher, blocks), matched_blocks|
|
59
|
+
if matcher.match?(path)
|
60
|
+
matched_blocks.concat(blocks)
|
61
|
+
end
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
# @api private
|
66
|
+
def watch_callback(path, _event)
|
67
|
+
change_callbacks(path).each do |callback|
|
68
|
+
instance_exec(&callback)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|