kirei 0.9.3 → 0.10.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.
- checksums.yaml +4 -4
- data/lib/cli/commands/new_app/files/app.rb +4 -1
- data/lib/cli/commands/new_app/files/routes.rb +2 -30
- data/lib/kirei/controllers/health.rb +63 -0
- data/lib/kirei/routing/base.rb +26 -2
- data/lib/kirei/routing/router.rb +12 -0
- data/lib/kirei/routing/verb.rb +0 -6
- data/lib/kirei/version.rb +1 -1
- data/lib/kirei.rb +1 -3
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1926e641bc2fa378b9444e97f33c7aef0bd97ce3c277a38fc572f12d501acb77
|
|
4
|
+
data.tar.gz: 2cdaff92504ea20fac445d791da1f9557fe3fbe6f4f780eab70c9022feacb3e1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4111679c635210bd6a9389c839c2665e5fea9a1e4bd3e6186725e89022a8964cf7a2dc8c2b5347eaf76962b327a7c0a77243cfc7c6ac214e01f59592a08a132f
|
|
7
|
+
data.tar.gz: 8aaf9c748f52d790cc2be69cb29087c96f1ad1001ee629555b5727d93770a1b73be72fbb62a8d1b3993a3ef75676832463b401cb265e5dd18a277d9706b9fc68
|
|
@@ -44,7 +44,10 @@ module Cli
|
|
|
44
44
|
|
|
45
45
|
# Fifth: load configs
|
|
46
46
|
Dir[File.join(__dir__, "config", "**", "*.rb")].each do |cnf|
|
|
47
|
-
|
|
47
|
+
next if cnf.split("/").include?("initializers")
|
|
48
|
+
next if cnf.end_with?("puma.rb") # Puma config uses DSL only available when loaded by Puma
|
|
49
|
+
|
|
50
|
+
require(cnf)
|
|
48
51
|
end
|
|
49
52
|
|
|
50
53
|
class #{app_name} < Kirei::App
|
|
@@ -5,10 +5,9 @@ module Cli
|
|
|
5
5
|
module NewApp
|
|
6
6
|
module Files
|
|
7
7
|
class Routes
|
|
8
|
-
def self.call(
|
|
8
|
+
def self.call(_app_name)
|
|
9
9
|
File.write("config/routes.rb", router)
|
|
10
10
|
File.write("app/controllers/base.rb", base_controller)
|
|
11
|
-
File.write("app/controllers/health.rb", health_controller(app_name))
|
|
12
11
|
end
|
|
13
12
|
|
|
14
13
|
def self.router
|
|
@@ -17,16 +16,7 @@ module Cli
|
|
|
17
16
|
# frozen_string_literal: true
|
|
18
17
|
|
|
19
18
|
module Kirei::Routing
|
|
20
|
-
Router.
|
|
21
|
-
[
|
|
22
|
-
Route.new(
|
|
23
|
-
verb: Verb::GET,
|
|
24
|
-
path: "/livez",
|
|
25
|
-
controller: Controllers::Health,
|
|
26
|
-
action: "livez",
|
|
27
|
-
),
|
|
28
|
-
],
|
|
29
|
-
)
|
|
19
|
+
Router.add_health_routes!
|
|
30
20
|
end
|
|
31
21
|
RUBY
|
|
32
22
|
end
|
|
@@ -43,24 +33,6 @@ module Cli
|
|
|
43
33
|
end
|
|
44
34
|
RUBY
|
|
45
35
|
end
|
|
46
|
-
|
|
47
|
-
def self.health_controller(app_name)
|
|
48
|
-
<<~RUBY
|
|
49
|
-
# typed: strict
|
|
50
|
-
# frozen_string_literal: true
|
|
51
|
-
|
|
52
|
-
module Controllers
|
|
53
|
-
class Health < Base
|
|
54
|
-
sig { returns(T.anything) }
|
|
55
|
-
def livez
|
|
56
|
-
#{app_name}.config.logger.info("Health check")
|
|
57
|
-
#{app_name}.config.logger.info(params.inspect)
|
|
58
|
-
render(#{app_name}.version, status: 200)
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
RUBY
|
|
63
|
-
end
|
|
64
36
|
end
|
|
65
37
|
end
|
|
66
38
|
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Kirei
|
|
5
|
+
module Controllers
|
|
6
|
+
#
|
|
7
|
+
# Built-in health check controller implementing Kubernetes API health endpoints.
|
|
8
|
+
#
|
|
9
|
+
# Provides three endpoints following the Kubernetes convention:
|
|
10
|
+
# - /livez — Liveness probe. Indicates the process is alive.
|
|
11
|
+
# - /readyz — Readiness probe. Verifies downstream dependencies (DB) are reachable.
|
|
12
|
+
# - /healthz — Deprecated alias for /livez (deprecated since Kubernetes v1.16).
|
|
13
|
+
#
|
|
14
|
+
# Reference: https://kubernetes.io/docs/reference/using-api/health-checks/
|
|
15
|
+
#
|
|
16
|
+
class Health < Kirei::Controller
|
|
17
|
+
extend T::Sig
|
|
18
|
+
|
|
19
|
+
sig { returns(Routing::RackResponseType) }
|
|
20
|
+
def livez
|
|
21
|
+
info = {
|
|
22
|
+
"status" => "ok",
|
|
23
|
+
"version" => App.version,
|
|
24
|
+
"app_name" => App.config.app_name,
|
|
25
|
+
"environment" => App.environment,
|
|
26
|
+
"req_host" => request.host,
|
|
27
|
+
"req_port" => request.port,
|
|
28
|
+
"req_ssl" => request.ssl?,
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
Kirei::Logging::Logger.call(
|
|
32
|
+
level: Kirei::Logging::Level::INFO,
|
|
33
|
+
label: "Health check",
|
|
34
|
+
meta: info,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
render_json(info, status: 200)
|
|
38
|
+
end
|
|
39
|
+
alias healthz livez
|
|
40
|
+
|
|
41
|
+
sig { returns(Routing::RackResponseType) }
|
|
42
|
+
def readyz
|
|
43
|
+
T.unsafe(App.raw_db_connection).execute("SELECT 1")
|
|
44
|
+
|
|
45
|
+
Kirei::Logging::Logger.call(
|
|
46
|
+
level: Kirei::Logging::Level::INFO,
|
|
47
|
+
label: "Readiness check",
|
|
48
|
+
meta: { "status" => "ok" },
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
render_json({ "status" => "ok" }, status: 200)
|
|
52
|
+
rescue Sequel::Error => e
|
|
53
|
+
Kirei::Logging::Logger.call(
|
|
54
|
+
level: Kirei::Logging::Level::ERROR,
|
|
55
|
+
label: "Readiness check failed",
|
|
56
|
+
meta: { "error" => e.message },
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
render_json({ "status" => "unavailable", "reason" => e.message }, status: 503)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
data/lib/kirei/routing/base.rb
CHANGED
|
@@ -63,7 +63,7 @@ module Kirei
|
|
|
63
63
|
body.rewind # TODO: maybe don't rewind if we don't need to?
|
|
64
64
|
T.cast(res, T::Hash[String, T.untyped])
|
|
65
65
|
end
|
|
66
|
-
when Verb::HEAD, Verb::DELETE, Verb::OPTIONS
|
|
66
|
+
when Verb::HEAD, Verb::DELETE, Verb::OPTIONS
|
|
67
67
|
{}
|
|
68
68
|
else
|
|
69
69
|
T.absurd(http_verb)
|
|
@@ -95,7 +95,7 @@ module Kirei
|
|
|
95
95
|
statsd_timing_tags["route"] = route.action
|
|
96
96
|
|
|
97
97
|
status, headers, response_body = case http_verb
|
|
98
|
-
when Verb::HEAD, Verb::OPTIONS
|
|
98
|
+
when Verb::HEAD, Verb::OPTIONS
|
|
99
99
|
[200, {}, []]
|
|
100
100
|
when Verb::GET, Verb::POST, Verb::PUT, Verb::PATCH, Verb::DELETE
|
|
101
101
|
T.cast(
|
|
@@ -122,6 +122,30 @@ module Kirei
|
|
|
122
122
|
headers,
|
|
123
123
|
response_body,
|
|
124
124
|
]
|
|
125
|
+
rescue StandardError => e
|
|
126
|
+
status = 500
|
|
127
|
+
|
|
128
|
+
Kirei::Logging::Logger.call(
|
|
129
|
+
level: Kirei::Logging::Level::ERROR,
|
|
130
|
+
label: "Unhandled Exception",
|
|
131
|
+
meta: {
|
|
132
|
+
"error.class" => e.class.name,
|
|
133
|
+
"error.message" => e.message,
|
|
134
|
+
"error.backtrace" => e.backtrace&.first(10)&.join("\n"),
|
|
135
|
+
},
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
detail = if Kirei::App.environment == "development"
|
|
139
|
+
"#{e.class}: #{e.message}\n#{e.backtrace&.first(10)&.join("\n")}"
|
|
140
|
+
else
|
|
141
|
+
"An unexpected error occurred"
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
error = Errors::JsonApiError.new(code: "internal_server_error", detail: detail)
|
|
145
|
+
body = Oj.dump({ "errors" => [error.serialize] }, Kirei::OJ_OPTIONS)
|
|
146
|
+
response_body = [body]
|
|
147
|
+
|
|
148
|
+
[status, { "Content-Type" => "application/json; charset=utf-8" }, response_body]
|
|
125
149
|
ensure
|
|
126
150
|
stop = Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond)
|
|
127
151
|
if start && statsd_timing_tags # early return for 404
|
data/lib/kirei/routing/router.rb
CHANGED
|
@@ -85,6 +85,18 @@ module Kirei
|
|
|
85
85
|
end
|
|
86
86
|
end
|
|
87
87
|
|
|
88
|
+
# must be added manually => we don't want to magically add routes for the user
|
|
89
|
+
sig { void }
|
|
90
|
+
def self.add_health_routes!
|
|
91
|
+
add_routes(
|
|
92
|
+
[
|
|
93
|
+
Route.new(verb: Verb::GET, path: "/livez", controller: Kirei::Controllers::Health, action: "livez"),
|
|
94
|
+
Route.new(verb: Verb::GET, path: "/readyz", controller: Kirei::Controllers::Health, action: "readyz"),
|
|
95
|
+
Route.new(verb: Verb::GET, path: "/healthz", controller: Kirei::Controllers::Health, action: "healthz"),
|
|
96
|
+
],
|
|
97
|
+
)
|
|
98
|
+
end
|
|
99
|
+
|
|
88
100
|
# Matches a request path against registered dynamic routes.
|
|
89
101
|
# Returns [Route, extracted_params] or nil.
|
|
90
102
|
sig do
|
data/lib/kirei/routing/verb.rb
CHANGED
data/lib/kirei/version.rb
CHANGED
data/lib/kirei.rb
CHANGED
|
@@ -67,6 +67,4 @@ loader.eager_load
|
|
|
67
67
|
|
|
68
68
|
Kirei.configure(&:itself)
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
Kirei::Logging::Logger.logger.info("Kirei v#{Kirei::VERSION} booted; YJIT enabled: #{yjit_enabled}")
|
|
70
|
+
Kirei::Logging::Logger.logger.info("Kirei v#{Kirei::VERSION} booted")
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kirei
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.10.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ludwig Reinmiedl
|
|
@@ -174,6 +174,7 @@ files:
|
|
|
174
174
|
- lib/kirei/app.rb
|
|
175
175
|
- lib/kirei/config.rb
|
|
176
176
|
- lib/kirei/controller.rb
|
|
177
|
+
- lib/kirei/controllers/health.rb
|
|
177
178
|
- lib/kirei/domain/entity.rb
|
|
178
179
|
- lib/kirei/domain/value_object.rb
|
|
179
180
|
- lib/kirei/errors/json_api_error.rb
|
|
@@ -226,7 +227,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
226
227
|
- !ruby/object:Gem::Version
|
|
227
228
|
version: '0'
|
|
228
229
|
requirements: []
|
|
229
|
-
rubygems_version: 4.0.
|
|
230
|
+
rubygems_version: 4.0.6
|
|
230
231
|
specification_version: 4
|
|
231
232
|
summary: Kirei is a typed Ruby micro/REST-framework for building scalable and performant
|
|
232
233
|
microservices.
|