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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e4a3c571b78f3b40e68be644fd1600d01e4d4cc6d4801ff391bd19d2f4c9b309
4
- data.tar.gz: 38e2ebe1345eea2e527f9538627436d1aa15970ccf4cc2531d0a18a371589bd9
3
+ metadata.gz: 1926e641bc2fa378b9444e97f33c7aef0bd97ce3c277a38fc572f12d501acb77
4
+ data.tar.gz: 2cdaff92504ea20fac445d791da1f9557fe3fbe6f4f780eab70c9022feacb3e1
5
5
  SHA512:
6
- metadata.gz: b9f0950c53791800f8815ea62c7b5f3f97697b9f6f8095070f49d80a35dfccee84d5b47ab6d5ec34864f9d25bc7c542b9e2cf9ebfd61bc6d9b84d5ad2dee7bf2
7
- data.tar.gz: c842729e9d31eceff4e4c50d592ed592658156632b7353707030c7e07064b216d3530116405f957b16ce00f9ea9be24ae4b8edeb28c1bfe9b7924e3ac7b69a2d
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
- require(cnf) unless cnf.split("/").include?("initializers")
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(app_name)
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.add_routes(
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
@@ -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, Verb::TRACE, Verb::CONNECT
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, Verb::TRACE, Verb::CONNECT
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
@@ -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
@@ -25,12 +25,6 @@ module Kirei
25
25
 
26
26
  # idempotent
27
27
  OPTIONS = new("OPTIONS")
28
-
29
- # idempotent
30
- TRACE = new("TRACE")
31
-
32
- # non-idempotent
33
- CONNECT = new("CONNECT")
34
28
  end
35
29
  end
36
30
  end
data/lib/kirei/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Kirei
5
- VERSION = "0.9.3"
5
+ VERSION = "0.10.0"
6
6
  end
data/lib/kirei.rb CHANGED
@@ -67,6 +67,4 @@ loader.eager_load
67
67
 
68
68
  Kirei.configure(&:itself)
69
69
 
70
- yjit_enabled = defined?(RubyVM::YJIT) ? RubyVM::YJIT.enabled? : false
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.9.3
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.3
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.