pakyow-core 1.0.0.rc5 → 1.0.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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/lib/pakyow/{environment/actions → actions}/dispatch.rb +0 -0
  4. data/lib/pakyow/{environment/actions → actions}/input_parser.rb +0 -0
  5. data/lib/pakyow/{environment/actions → actions}/logger.rb +0 -0
  6. data/lib/pakyow/{environment/actions → actions}/normalizer.rb +0 -0
  7. data/lib/pakyow/{app.rb → application.rb} +26 -26
  8. data/lib/pakyow/application/behavior/aspects.rb +51 -0
  9. data/lib/pakyow/application/behavior/endpoints.rb +43 -0
  10. data/lib/pakyow/application/behavior/frameworks.rb +47 -0
  11. data/lib/pakyow/application/behavior/helpers.rb +107 -0
  12. data/lib/pakyow/{environment → application}/behavior/initializers.rb +4 -4
  13. data/lib/pakyow/application/behavior/isolating.rb +71 -0
  14. data/lib/pakyow/application/behavior/operations.rb +49 -0
  15. data/lib/pakyow/application/behavior/pipeline.rb +60 -0
  16. data/lib/pakyow/application/behavior/plugins.rb +151 -0
  17. data/lib/pakyow/application/behavior/rescuing.rb +53 -0
  18. data/lib/pakyow/application/behavior/restarting.rb +72 -0
  19. data/lib/pakyow/application/behavior/sessions.rb +38 -0
  20. data/lib/pakyow/{behavior → application}/config.rb +1 -1
  21. data/lib/pakyow/{app → application}/connection.rb +4 -4
  22. data/lib/pakyow/{app → application}/connection/behavior/session.rb +1 -1
  23. data/lib/pakyow/{app → application}/connection/behavior/values.rb +1 -1
  24. data/lib/pakyow/{app → application}/connection/behavior/verifier.rb +1 -1
  25. data/lib/pakyow/{app → application}/connection/session/base.rb +1 -1
  26. data/lib/pakyow/{app → application}/connection/session/cookie.rb +2 -2
  27. data/lib/pakyow/application/helpers/app.rb +30 -0
  28. data/lib/pakyow/application/helpers/connection.rb +47 -0
  29. data/lib/pakyow/behavior/initializers.rb +3 -3
  30. data/lib/pakyow/behavior/input_parsing.rb +55 -0
  31. data/lib/pakyow/behavior/plugins.rb +3 -130
  32. data/lib/pakyow/behavior/restarting.rb +28 -46
  33. data/lib/pakyow/behavior/running.rb +127 -0
  34. data/lib/pakyow/behavior/silencing.rb +21 -0
  35. data/lib/pakyow/behavior/timezone.rb +19 -0
  36. data/lib/pakyow/behavior/verification.rb +1 -1
  37. data/lib/pakyow/behavior/verifier.rb +30 -0
  38. data/lib/pakyow/behavior/watching.rb +73 -0
  39. data/lib/pakyow/config.rb +168 -0
  40. data/lib/pakyow/environment.rb +31 -31
  41. data/lib/pakyow/helper.rb +9 -0
  42. data/lib/pakyow/loader.rb +7 -1
  43. data/lib/pakyow/plugin.rb +22 -21
  44. metadata +42 -42
  45. data/lib/pakyow/behavior/aspects.rb +0 -49
  46. data/lib/pakyow/behavior/endpoints.rb +0 -41
  47. data/lib/pakyow/behavior/frameworks.rb +0 -45
  48. data/lib/pakyow/behavior/helpers.rb +0 -108
  49. data/lib/pakyow/behavior/isolating.rb +0 -69
  50. data/lib/pakyow/behavior/operations.rb +0 -47
  51. data/lib/pakyow/behavior/pipeline.rb +0 -58
  52. data/lib/pakyow/behavior/rescuing.rb +0 -51
  53. data/lib/pakyow/behavior/sessions.rb +0 -36
  54. data/lib/pakyow/environment/behavior/config.rb +0 -172
  55. data/lib/pakyow/environment/behavior/input_parsing.rb +0 -57
  56. data/lib/pakyow/environment/behavior/plugins.rb +0 -23
  57. data/lib/pakyow/environment/behavior/restarting.rb +0 -54
  58. data/lib/pakyow/environment/behavior/running.rb +0 -129
  59. data/lib/pakyow/environment/behavior/silencing.rb +0 -23
  60. data/lib/pakyow/environment/behavior/timezone.rb +0 -21
  61. data/lib/pakyow/environment/behavior/verifier.rb +0 -32
  62. data/lib/pakyow/environment/behavior/watching.rb +0 -75
  63. data/lib/pakyow/helpers/app.rb +0 -28
  64. data/lib/pakyow/helpers/connection.rb +0 -45
@@ -0,0 +1,127 @@
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 Behavior
15
+ module Running
16
+ extend Support::Extension
17
+
18
+ apply_extension do
19
+ unfreezable :process_manager
20
+
21
+ class_state :processes, default: []
22
+
23
+ on "run" do
24
+ if config.server.proxy
25
+ # Find a port to run the environment on, start the proxy on the configured port.
26
+ #
27
+ port = Processes::Proxy.find_local_port
28
+ process :proxy, restartable: false do
29
+ Processes::Proxy.new(
30
+ host: config.server.host,
31
+ port: config.server.port,
32
+ proxy_port: port
33
+ ).run
34
+ end
35
+ else
36
+ # Run the environment on the configured port.
37
+ #
38
+ port = config.server.port
39
+ end
40
+
41
+ endpoint = Async::HTTP::Endpoint.parse(
42
+ "http://#{config.server.host}:#{port}"
43
+ )
44
+
45
+ bound_endpoint = Async::Reactor.run {
46
+ Async::IO::SharedEndpoint.bound(endpoint)
47
+ }.wait
48
+
49
+ process :server, count: config.server.count do
50
+ Pakyow.config.server.port = port
51
+
52
+ Processes::Server.new(
53
+ protocol: endpoint.protocol,
54
+ scheme: endpoint.scheme,
55
+ endpoint: bound_endpoint
56
+ ).run
57
+ end
58
+
59
+ unless config.server.proxy || ENV.key?("PW_RESPAWN")
60
+ Pakyow.logger << Processes::Server.running_text(
61
+ scheme: endpoint.scheme, host: config.server.host, port: port
62
+ )
63
+ end
64
+ end
65
+ end
66
+
67
+ class_methods do
68
+ def process(name, count: 1, restartable: true, &block)
69
+ @processes << {
70
+ name: name,
71
+ block: block,
72
+ count: count,
73
+ restartable: restartable
74
+ }
75
+ end
76
+
77
+ def run
78
+ performing :run do
79
+ @process_manager = @processes.each_with_object(ProcessManager.new) { |process, manager|
80
+ manager.add(process)
81
+ }
82
+
83
+ root_pid = Process.pid
84
+
85
+ at_exit do
86
+ if Process.pid == root_pid
87
+ shutdown
88
+ else
89
+ @apps.select { |app|
90
+ app.respond_to?(:shutdown)
91
+ }.each(&:shutdown)
92
+ end
93
+ end
94
+ end
95
+
96
+ @process_manager.wait
97
+
98
+ if @respawn
99
+ # Replace the master process with a copy of itself.
100
+ #
101
+ exec "PW_RESPAWN=true #{$0} #{ARGV.join(" ")}"
102
+ end
103
+ rescue SignalException
104
+ exit
105
+ end
106
+
107
+ def shutdown
108
+ if $stdout.isatty
109
+ # Don't let ^C mess up our output.
110
+ #
111
+ puts
112
+ end
113
+
114
+ Pakyow.logger << "Goodbye"
115
+
116
+ performing :shutdown do
117
+ @process_manager.stop
118
+ end
119
+ end
120
+
121
+ def restart
122
+ @process_manager.restart
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pakyow/support/extension"
4
+
5
+ module Pakyow
6
+ module Behavior
7
+ module Silencing
8
+ extend Support::Extension
9
+
10
+ apply_extension do
11
+ class_state :silencers, default: []
12
+ end
13
+
14
+ class_methods do
15
+ def silence(&block)
16
+ @silencers << block
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pakyow/support/extension"
4
+
5
+ module Pakyow
6
+ module Behavior
7
+ # Sets up the timezone for the environment.
8
+ #
9
+ module Timezone
10
+ extend Support::Extension
11
+
12
+ apply_extension do
13
+ after "configure" do
14
+ ENV["TZ"] = config.timezone.to_s
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -23,7 +23,7 @@ module Pakyow
23
23
  end
24
24
 
25
25
  original_values = values.deep_dup
26
- result = Verifier.new(&block).call(values, context: self)
26
+ result = Pakyow::Verifier.new(&block).call(values, context: self)
27
27
 
28
28
  unless result.verified?
29
29
  error = InvalidData.new_with_message(:verification)
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pakyow/support/extension"
4
+ require "pakyow/support/message_verifier"
5
+
6
+ module Pakyow
7
+ module Behavior
8
+ module Verifier
9
+ extend Support::Extension
10
+
11
+ class_methods do
12
+ attr_reader :verifier
13
+ end
14
+
15
+ apply_extension do
16
+ before :boot do
17
+ config.secrets.reject! { |secret|
18
+ secret.nil? || secret.empty?
19
+ }
20
+
21
+ if config.secrets.any?
22
+ @verifier = Support::MessageVerifier.new(config.secrets[0])
23
+ else
24
+ raise "Pakyow will not boot without a secret configured in `Pakyow.config.secrets`"
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "filewatcher"
4
+
5
+ require "pakyow/support/extension"
6
+
7
+ module Pakyow
8
+ module Behavior
9
+ module Watching
10
+ extend Support::Extension
11
+
12
+ apply_extension do
13
+ class_state :on_change_matchers, default: {}
14
+ class_state :watched_paths, default: []
15
+
16
+ unfreezable :filewatcher, :filewatcher_thread
17
+
18
+ after "run" do
19
+ @filewatcher = Filewatcher.new(
20
+ @watched_paths.map { |path|
21
+ File.expand_path(path)
22
+ }
23
+ )
24
+
25
+ @filewatcher_thread = Thread.new do
26
+ @filewatcher.watch(&method(:watch_callback))
27
+ end
28
+ end
29
+
30
+ on "shutdown" do
31
+ @filewatcher.stop
32
+ @filewatcher_thread.join
33
+ end
34
+ end
35
+
36
+ class_methods do
37
+ # Register a callback to be called when a file changes.
38
+ #
39
+ def on_change(matcher, &block)
40
+ (@on_change_matchers[matcher] ||= []) << block
41
+ end
42
+
43
+ # Register one or more path for changes.
44
+ #
45
+ def watch(*paths, &block)
46
+ @watched_paths.concat(paths).uniq!
47
+
48
+ if block
49
+ paths.each do |path|
50
+ on_change(File.expand_path(path), &block)
51
+ end
52
+ end
53
+ end
54
+
55
+ # @api private
56
+ def change_callbacks(path)
57
+ @on_change_matchers.each_with_object([]) { |(matcher, blocks), matched_blocks|
58
+ if matcher.match?(path)
59
+ matched_blocks.concat(blocks)
60
+ end
61
+ }
62
+ end
63
+
64
+ # @api private
65
+ def watch_callback(path, _event)
66
+ change_callbacks(path).each do |callback|
67
+ instance_exec(&callback)
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,168 @@
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 Config
10
+ extend Support::Extension
11
+
12
+ apply_extension do
13
+ setting :default_env, :development
14
+ setting :freeze_on_boot, true
15
+ setting :exit_on_boot_failure, true
16
+ setting :timezone, :utc
17
+ setting :secrets, ["pakyow"]
18
+
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
+ defaults :production do
45
+ setting :secrets, [ENV["SECRET"].to_s.strip]
46
+ end
47
+
48
+ configurable :server do
49
+ setting :host, "localhost"
50
+ setting :port, 3000
51
+ setting :count, 1
52
+ setting :proxy, true
53
+
54
+ defaults :production do
55
+ setting :proxy, false
56
+
57
+ setting :host do
58
+ ENV["HOST"] || "0.0.0.0"
59
+ end
60
+
61
+ setting :port do
62
+ ENV["PORT"] || 3000
63
+ end
64
+
65
+ setting :count do
66
+ ENV["WORKERS"] || 5
67
+ end
68
+ end
69
+ end
70
+
71
+ configurable :cli do
72
+ setting :repl do
73
+ require "irb"; IRB
74
+ end
75
+ end
76
+
77
+ configurable :logger do
78
+ setting :enabled, true
79
+ setting :sync, true
80
+
81
+ setting :level do
82
+ if config.logger.enabled
83
+ :debug
84
+ else
85
+ :off
86
+ end
87
+ end
88
+
89
+ setting :formatter do
90
+ Logger::Formatters::Human
91
+ end
92
+
93
+ setting :destinations do
94
+ if config.logger.enabled
95
+ { stdout: $stdout }
96
+ else
97
+ {}
98
+ end
99
+ end
100
+
101
+ defaults :test do
102
+ setting :enabled, false
103
+ end
104
+
105
+ defaults :production do
106
+ setting :level do
107
+ if config.logger.enabled
108
+ :info
109
+ else
110
+ :off
111
+ end
112
+ end
113
+
114
+ setting :formatter do
115
+ Logger::Formatters::Logfmt
116
+ end
117
+ end
118
+
119
+ defaults :ludicrous do
120
+ setting :enabled, false
121
+ end
122
+ end
123
+
124
+ configurable :normalizer do
125
+ setting :strict_path, true
126
+ setting :strict_www, false
127
+ setting :require_www, true
128
+ end
129
+
130
+ configurable :tasks do
131
+ setting :paths, ["./tasks", File.expand_path("../tasks", __FILE__)]
132
+ setting :prelaunch, []
133
+ end
134
+
135
+ configurable :redis do
136
+ configurable :connection do
137
+ setting :url do
138
+ ENV["REDIS_URL"] || "redis://127.0.0.1:6379"
139
+ end
140
+
141
+ setting :timeout, 5
142
+ setting :driver, nil
143
+ setting :id, nil
144
+ setting :tcp_keepalive, 5
145
+ setting :reconnect_attempts, 1
146
+ setting :inherit_socket, false
147
+ end
148
+
149
+ configurable :pool do
150
+ setting :size, 3
151
+ setting :timeout, 1
152
+ end
153
+
154
+ setting :key_prefix, "pw"
155
+ end
156
+
157
+ configurable :cookies do
158
+ setting :domain
159
+ setting :path, "/"
160
+ setting :max_age
161
+ setting :expires
162
+ setting :secure
163
+ setting :http_only
164
+ setting :same_site
165
+ end
166
+ end
167
+ end
168
+ end