forked from ubicloud/ubicloud
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathloader.rb
More file actions
235 lines (193 loc) · 6.55 KB
/
loader.rb
File metadata and controls
235 lines (193 loc) · 6.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# frozen_string_literal: true
require_relative "lib/thread_printer"
Signal.trap("QUIT") do
ThreadPrinter.run
Kernel.exit!(Signal.list["QUIT"] + 128)
end
require "bundler"
rack_env = ENV["RACK_ENV"] || "development"
Bundler.setup(:default, rack_env.to_sym)
require_relative "config"
require "mail"
require "warning"
require "rack/unreloader"
REPL = false unless defined? REPL
Warning.ignore(/To use (retry|multipart) middleware with Faraday v2\.0\+, install `faraday-(retry|multipart)` gem/)
force_autoload = Config.production? || ENV["FORCE_AUTOLOAD"] == "1"
Unreloader = Rack::Unreloader.new(reload: Config.development?, autoload: true) { Clover }
autoload :DB, "#{__dir__}/db.rb"
Unreloader.autoload("#{__dir__}/ubid.rb") { "UBID" }
AUTOLOAD_CONSTANTS = ["UBID"]
# Set up autoloads using Unreloader using a style much like Zeitwerk:
# directories are modules, file names are classes.
autoload_normal = ->(subdirectory, include_first: false, flat: false) do
absolute = File.join(__dir__, subdirectory)
rgx = if flat
# No matter how deep the file system traversal, this Regexp
# only matches the filename in its capturing group,
# i.e. it's like File.basename.
Regexp.new('\A.*?([^/]*)\.rb\z')
else
# Capture the relative path of a traversed file, by using
# Regexp.escape on the prefix that should *not* be
# interpreted as modules/namespaces. Since this is works on
# absolute paths, the ignored content will often be like
# "/home/myuser/..."
Regexp.new('\A' + Regexp.escape((File.file?(absolute) ? File.dirname(absolute) : absolute) + "/") + '(.*)\.rb\z')
end
# Copied from sequel/model/inflections.rb's camelize, to convert
# file paths into module and class names.
camelize = ->(s) do
s.gsub(/\/(.?)/) { |x| "::#{x[-1..].upcase}" }.gsub(/(^|_)(.)/) { |x| x[-1..].upcase }
end
Unreloader.autoload(absolute) do |f|
full_name = camelize.call((include_first ? subdirectory + File::SEPARATOR : "") + rgx.match(f)[1])
AUTOLOAD_CONSTANTS << full_name unless AUTOLOAD_CONSTANTS.frozen?
full_name
end
end
# Define empty modules instead of trying to have autoload_normal create them via metaprogramming
module Hosting; end
module Minio; end
module Prog; end
module Prog::Ai; end
module Prog::DnsZone; end
module Prog::Github; end
module Prog::Kubernetes; end
module Prog::Minio; end
module Prog::Postgres; end
module Prog::Storage; end
module Prog::Vm; end
module Prog::Vnet; end
module Scheduling; end
module Serializers; end
autoload_normal.call("model", flat: true)
%w[lib clover.rb].each { autoload_normal.call(_1) }
%w[scheduling prog serializers].each { autoload_normal.call(_1, include_first: true) }
if ENV["LOAD_FILES_SEPARATELY_CHECK"] == "1"
files = %w[model lib scheduling prog serializers].flat_map { Dir["#{_1}/**/*.rb"] }
files << "clover.rb"
Sequel::DATABASES.each(&:disconnect)
files.each do |file|
pid = fork do
require_relative file
exit(0)
rescue LoadError, StandardError => e
puts "ERROR: problems loading #{file}: #{e.class}: #{e.message}"
end
Process.wait(pid)
end
exit(0)
end
AUTOLOAD_CONSTANTS.freeze
Unreloader.record_dependency("lib/authorization.rb", "model")
Unreloader.record_dependency("lib/health_monitor_methods.rb", "model")
Unreloader.record_dependency("lib/resource_methods.rb", "model")
Unreloader.record_dependency("lib/semaphore_methods.rb", "model")
if force_autoload
AUTOLOAD_CONSTANT_VALUES = AUTOLOAD_CONSTANTS.map { Object.const_get(_1) }.freeze
# All classes are already available, so speed up UBID.class_for_ubid using
# hash of prefixes to class objects
class UBID
TYPE2CLASS = TYPE2CLASSNAME.transform_values { Object.const_get(_1) }.freeze
private_constant :TYPE2CLASS
singleton_class.remove_method(:class_for_ubid)
def self.class_for_ubid(str)
TYPE2CLASS[str[..1]]
end
end
end
case Config.mail_driver
when :smtp
::Mail.defaults do
delivery_method :smtp, {
address: Config.smtp_hostname,
port: Config.smtp_port,
user_name: Config.smtp_user,
password: Config.smtp_password,
authentication: :plain,
enable_starttls: Config.smtp_tls
}
end
when :logger
::Mail.defaults do
delivery_method :logger
end
when :test
::Mail.defaults do
delivery_method :test
end
end
def clover_freeze
return unless Config.production? || ENV["CLOVER_FREEZE"] == "1"
require "refrigerator"
# Take care of library dependencies that modify core classes.
# For at least Puma, per
# https://github.com/jeremyevans/roda-sequel-stack/blob/931e810a802b2ab14628111cfce596998316b556/config.ru#L41C6-L42C1
require "yaml"
# Also for at least puma, but not itemized by the roda-sequel-stack
# project for some reason.
require "nio4r"
# this Ruby standard library method patches core classes.
"".unicode_normalize(:nfc)
# Aws SDK started to autoload modules when used, so we need to load them
# before freezing. https://github.com/aws/aws-sdk-ruby/pull/3105
[:Client, :Presigner, :Errors].each { Aws::S3.const_get(_1) }
# A standard library method that edits/creates a module variable as
# a side effect. We encountered it when using rubygems for its tar
# file writing.
Gem.source_date_epoch
# Freeze all constants that are autoloaded
DB.freeze
Sequel::Model.freeze_descendants
AUTOLOAD_CONSTANT_VALUES.each(&:freeze)
[
Authorization,
Authorization::Unauthorized,
HealthMonitorMethods,
Hosting,
Minio,
Minio::Client::Blob,
Minio::Crypto::AesGcmCipherProvider,
PostgresResource::Flavor,
PostgresResource::HaType,
Prog,
Prog::Ai,
Prog::Base::Exit,
Prog::Base::FlowControl,
Prog::Base::Hop,
Prog::Base::Nap,
Prog::DnsZone,
Prog::Github,
Prog::Kubernetes,
Prog::Minio,
Prog::Postgres,
Prog::Storage,
Prog::Vm,
Prog::Vnet,
Prog::Vnet::RekeyNicTunnel::Xfrm,
ResourceMethods,
ResourceMethods::ClassMethods,
Scheduling,
Scheduling::Allocator,
Scheduling::Allocator::Allocation,
Scheduling::Allocator::GpuAllocation,
Scheduling::Allocator::StorageAllocation,
Scheduling::Allocator::StorageAllocation::StorageDeviceAllocation,
Scheduling::Allocator::VmHostAllocation,
Scheduling::Allocator::VmHostCpuAllocation,
Scheduling::Allocator::VmHostSliceAllocation,
SemaphoreMethods,
SemaphoreMethods::ClassMethods,
Sequel::Database,
Sequel::Dataset,
SequelExtensions,
Sequel::Model,
Serializers,
Serializers::Base,
Sshable::SshError,
Validation,
Validation::ValidationFailed
].each(&:freeze)
Refrigerator.freeze_core
end