Module: Xeno::Standalone
- Defined in:
- lib/xeno/standalone.rb,
lib/xeno/standalone/local_secret.rb,
lib/xeno/standalone/model_refresh.rb
Class Method Summary collapse
-
.boot! ⇒ Object
Boot: initialize the app, then bring the database up to date — the engine's migrations plus Solid Queue's tables (loaded straight from the solid_queue gem's install template).
-
.local_secret(root) ⇒ Object
A persisted local secret so sessions survive restarts without asking anyone to manage SECRET_KEY_BASE for a dev-grade standalone app.
- .migrate! ⇒ Object
-
.puma_config_path ⇒ Object
The gem-owned puma config used by
xeno server— Solid Queue runs inside Puma (SOLID_QUEUE_IN_PUMA), one process total. - .queue_schema_path ⇒ Object
-
.refresh_models! ⇒ Object
First boot only (the registry table is empty): pull the live model catalog from the configured providers so current model ids resolve without a manual RubyLLM.models.refresh!.
-
.write_recurring_config! ⇒ Object
Solid Queue's recurring machinery is how the reaper (always) and the compiled schedules (outside development) fire in standalone mode.
Class Method Details
.boot! ⇒ Object
Boot: initialize the app, then bring the database up to date — the engine's migrations plus Solid Queue's tables (loaded straight from the solid_queue gem's install template).
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/xeno/standalone.rb', line 73 def boot! ENV["RAILS_ENV"] ||= "development" FileUtils.mkdir_p(StandaloneApplication::APP_ROOT.join("storage")) app = Rails.application || StandaloneApplication.instance unless app.initialized? app.initialize! app.routes.draw do mount Xeno::Engine => "/agent" root to: redirect("/agent/dev") end end migrate! refresh_models! write_recurring_config! Rails.application end |
.local_secret(root) ⇒ Object
A persisted local secret so sessions survive restarts without asking anyone to manage SECRET_KEY_BASE for a dev-grade standalone app. Owner-only (0600) — it signs cookies/sessions (S6); pre-existing looser files are tightened on read.
Lives apart from xeno/standalone so tests can exercise it without defining the Rails::Application (which self-registers on inheritance).
15 16 17 18 19 20 21 22 23 24 |
# File 'lib/xeno/standalone/local_secret.rb', line 15 def local_secret(root) path = root.join("storage", ".local_secret") FileUtils.mkdir_p(path.dirname) if path.file? File.chmod(0o600, path) return path.read.strip end SecureRandom.hex(64).tap { |secret| File.write(path, secret, perm: 0o600) } end |
.migrate! ⇒ Object
112 113 114 115 116 117 118 119 |
# File 'lib/xeno/standalone.rb', line 112 def migrate! ActiveRecord::MigrationContext.new([ Xeno::Engine.root.join("db", "migrate").to_s ]).migrate connection = ActiveRecord::Base.lease_connection unless connection.table_exists?("solid_queue_jobs") load queue_schema_path end end |
.puma_config_path ⇒ Object
The gem-owned puma config used by xeno server — Solid Queue runs
inside Puma (SOLID_QUEUE_IN_PUMA), one process total.
128 129 130 |
# File 'lib/xeno/standalone.rb', line 128 def puma_config_path File.("standalone/puma.rb", __dir__) end |
.queue_schema_path ⇒ Object
121 122 123 124 |
# File 'lib/xeno/standalone.rb', line 121 def queue_schema_path spec = Gem::Specification.find_by_name("solid_queue") File.join(spec.gem_dir, "lib", "generators", "solid_queue", "install", "templates", "db", "queue_schema.rb") end |
.refresh_models! ⇒ Object
First boot only (the registry table is empty): pull the live model catalog from the configured providers so current model ids resolve without a manual RubyLLM.models.refresh!. Loading the definition first runs agent.rb's RubyLLM.configure — the refresh needs those provider keys. Never fatal, never repeated once the table has rows; skippable with XENO_SKIP_MODEL_REFRESH=1 (deterministic scripts, offline boots).
11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/xeno/standalone/model_refresh.rb', line 11 def refresh_models! return if ENV["XENO_SKIP_MODEL_REFRESH"] Xeno.definition store = RubyLLM.config.model_registry_store return unless store.respond_to?(:none?) && store.none? Rails.logger.info "xeno: first boot — refreshing the model registry" RubyLLM.models.refresh! Rails.logger.info "xeno: model registry ready (#{store.count} models)" rescue StandardError => error Rails.logger.warn "xeno: model registry refresh failed (#{error.class}: #{error.}). " \ "Continuing; run RubyLLM.models.refresh! manually if a model fails to resolve." end |
.write_recurring_config! ⇒ Object
Solid Queue's recurring machinery is how the reaper (always) and the compiled schedules (outside development) fire in standalone mode. The file lives under storage/ (gitignored) so the scaffold stays four visible files; the env var — read by Solid Queue's supervisor, which starts after config.ru has loaded — points the scheduler at it.
97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/xeno/standalone.rb', line 97 def write_recurring_config! section = { Xeno::Schedules::REAPER_KEY => Xeno::Schedules.reaper_entry } unless Rails.env.development? Xeno.definition.schedules.each do |name, schedule| section["#{Xeno::Schedules::MANAGED_PREFIX}#{name}"] = { "class" => "Xeno::ScheduleJob", "args" => [ name ], "schedule" => schedule.cron } end end path = StandaloneApplication::APP_ROOT.join("storage", "recurring.yml") File.write(path, YAML.dump({ Rails.env.to_s => section })) ENV["SOLID_QUEUE_RECURRING_SCHEDULE"] ||= File.join("storage", "recurring.yml") end |