Class: Takagi::Controller
- Inherits:
-
Object
- Object
- Takagi::Controller
- Extended by:
- Base::ReactorManagement
- Defined in:
- lib/takagi/controller.rb,
lib/takagi/controller/thread_pool.rb,
lib/takagi/controller/resource_allocator.rb
Overview
Base class for modular controllers with isolated routers
Controllers provide route isolation, independent process pools, and nested mounting capabilities for building scalable CoAP applications.
Direct Known Subclasses
Defined Under Namespace
Classes: ConfigContext, ResourceAllocator, ThreadPool
Class Method Summary collapse
-
.add_route(method, path, metadata: {}) { ... } ⇒ Object
Register a route with the controller’s isolated router.
-
.config ⇒ Hash
Get or create the controller’s configuration.
-
.configure { ... } ⇒ Object
Configure the controller.
-
.mount_path ⇒ String?
Get the full mount path for this controller.
-
.mounted? ⇒ Boolean
Check if controller has been configured with a mount path.
-
.nested_controllers ⇒ Array<Class>
Get all nested controllers.
-
.observable(path, metadata: {}) { ... } ⇒ Object
Register an observable route.
-
.process_count ⇒ Integer?
Get the effective process count.
-
.profile_name ⇒ Symbol?
Get the load profile name.
-
.router ⇒ Router
Get or create the controller’s isolated router.
-
.schedule { ... } ⇒ Object
Schedule a job to run in the controller’s thread pool.
-
.shutdown_workers! ⇒ Object
Shutdown the controller’s worker thread pool.
-
.start_workers!(threads: nil, name: nil) ⇒ ThreadPool
Start the controller’s worker thread pool.
-
.thread_count ⇒ Integer?
Get the effective thread count.
-
.thread_pool ⇒ ThreadPool
Get or create the controller’s thread pool.
-
.workers_running? ⇒ Boolean
Check if the controller’s thread pool is running.
Methods included from Base::ReactorManagement
reactor, start_reactors, stop_reactors, use_reactor
Class Method Details
.add_route(method, path, metadata: {}) { ... } ⇒ Object
Register a route with the controller’s isolated router
88 89 90 |
# File 'lib/takagi/controller.rb', line 88 def add_route(method, path, metadata: {}, &block) router.add_route(method, path, metadata: , &block) end |
.config ⇒ Hash
Get or create the controller’s configuration
57 58 59 60 61 62 63 64 65 66 |
# File 'lib/takagi/controller.rb', line 57 def config @config ||= { mount_path: nil, nested_from: nil, nested_controllers: [], profile: nil, processes: nil, threads: nil } end |
.configure { ... } ⇒ Object
Configure the controller
78 79 80 |
# File 'lib/takagi/controller.rb', line 78 def configure(&block) ConfigContext.new(self).instance_eval(&block) if block end |
.mount_path ⇒ String?
Get the full mount path for this controller
Resolves nested paths if controller is nested from a parent.
118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/takagi/controller.rb', line 118 def mount_path path = config[:mount_path] return nil unless path # If nested from parent, prepend parent's mount path if config[:nested_from] parent_path = config[:nested_from].mount_path return File.join(parent_path, path) if parent_path end path end |
.mounted? ⇒ Boolean
Check if controller has been configured with a mount path
134 135 136 |
# File 'lib/takagi/controller.rb', line 134 def mounted? !config[:mount_path].nil? end |
.nested_controllers ⇒ Array<Class>
Get all nested controllers
141 142 143 |
# File 'lib/takagi/controller.rb', line 141 def nested_controllers config[:nested_controllers] end |
.observable(path, metadata: {}) { ... } ⇒ Object
Register an observable route
108 109 110 111 |
# File 'lib/takagi/controller.rb', line 108 def observable(path, metadata: {}, &block) = { obs: true, rt: 'core#observable', if: 'takagi.observe' } add_route('OBSERVE', path, metadata: .merge(), &block) end |
.process_count ⇒ Integer?
Get the effective process count
Uses explicit :processes config, falls back to profile, or nil.
157 158 159 |
# File 'lib/takagi/controller.rb', line 157 def process_count config[:processes] || profile_config[:processes] end |
.profile_name ⇒ Symbol?
Get the load profile name
148 149 150 |
# File 'lib/takagi/controller.rb', line 148 def profile_name config[:profile] end |
.router ⇒ Router
Get or create the controller’s isolated router
Each controller has its own Router instance, unlike Takagi::Base which uses a global singleton router.
50 51 52 |
# File 'lib/takagi/controller.rb', line 50 def router @router ||= Router.new end |
.schedule { ... } ⇒ Object
Schedule a job to run in the controller’s thread pool
212 213 214 215 216 217 218 219 |
# File 'lib/takagi/controller.rb', line 212 def schedule(&block) unless @thread_pool error = Errors::ThreadPoolError.not_started(name) raise error end @thread_pool.schedule(&block) end |
.shutdown_workers! ⇒ Object
Shutdown the controller’s worker thread pool
199 200 201 202 203 204 205 206 |
# File 'lib/takagi/controller.rb', line 199 def shutdown_workers! return unless @thread_pool Takagi.logger.info "Shutting down worker pool for #{name}" Takagi::Hooks.emit(:controller_workers_stopped, controller: self) @thread_pool.shutdown @thread_pool = nil end |
.start_workers!(threads: nil, name: nil) ⇒ ThreadPool
Start the controller’s worker thread pool
188 189 190 191 192 193 194 195 196 |
# File 'lib/takagi/controller.rb', line 188 def start_workers!(threads: nil, name: nil) threads ||= thread_count || 4 # Default to 4 threads name ||= self.name.split('::').last # e.g., "IngressController" @thread_pool = ThreadPool.new(size: threads, name: name) Takagi.logger.info "Started worker pool for #{name} with #{threads} threads" Takagi::Hooks.emit(:controller_workers_started, controller: self, name: name, threads: threads) @thread_pool end |
.thread_count ⇒ Integer?
Get the effective thread count
Uses explicit :threads config, falls back to profile, or nil.
166 167 168 |
# File 'lib/takagi/controller.rb', line 166 def thread_count config[:threads] || profile_config[:threads] end |
.thread_pool ⇒ ThreadPool
Get or create the controller’s thread pool
Lazy initialization: creates pool on first access if not already started. This allows reactors to share the controller’s pool automatically.
176 177 178 179 180 181 |
# File 'lib/takagi/controller.rb', line 176 def thread_pool @thread_pool ||= begin Takagi.logger.debug "Lazy-initializing thread pool for #{name}" start_workers! end end |
.workers_running? ⇒ Boolean
Check if the controller’s thread pool is running
224 225 226 |
# File 'lib/takagi/controller.rb', line 224 def workers_running? @thread_pool && !@thread_pool.shutdown? end |