Module: Legion::DigitalWorker
- Defined in:
- lib/legion/digital_worker.rb,
lib/legion/digital_worker/airb.rb,
lib/legion/digital_worker/registry.rb,
lib/legion/digital_worker/lifecycle.rb,
lib/legion/digital_worker/risk_tier.rb,
lib/legion/digital_worker/registration.rb,
lib/legion/digital_worker/value_metrics.rb
Defined Under Namespace
Modules: Airb, Lifecycle, Registration, Registry, RiskTier, ValueMetrics
Class Method Summary collapse
- .active_local_ids ⇒ Object
- .active_workers ⇒ Object
- .by_owner(owner_msid:) ⇒ Object
- .by_team(team:) ⇒ Object
- .detect_orphans(stale_days: 7) ⇒ Object
- .find(worker_id:) ⇒ Object
- .find_by_entra_app(entra_app_id:) ⇒ Object
- .heartbeat(worker_id:, health_status: 'healthy', health_node: nil) ⇒ Object
- .pause_orphans!(stale_days: 7, by: 'system:orphan_detection') ⇒ Object
- .register(name:, extension_name:, entra_app_id:, owner_msid:, **opts) ⇒ Object
Class Method Details
.active_local_ids ⇒ Object
88 89 90 91 92 |
# File 'lib/legion/digital_worker.rb', line 88 def active_local_ids return [] unless defined?(Registry) Registry.local_worker_ids end |
.active_workers ⇒ Object
34 35 36 |
# File 'lib/legion/digital_worker.rb', line 34 def active_workers Legion::Data::Model::DigitalWorker.where(lifecycle_state: 'active') end |
.by_owner(owner_msid:) ⇒ Object
38 39 40 |
# File 'lib/legion/digital_worker.rb', line 38 def by_owner(owner_msid:) Legion::Data::Model::DigitalWorker.where(owner_msid: owner_msid) end |
.by_team(team:) ⇒ Object
42 43 44 |
# File 'lib/legion/digital_worker.rb', line 42 def by_team(team:) Legion::Data::Model::DigitalWorker.where(team: team) end |
.detect_orphans(stale_days: 7) ⇒ Object
56 57 58 59 60 61 62 |
# File 'lib/legion/digital_worker.rb', line 56 def detect_orphans(stale_days: 7) cutoff = Time.now.utc - (stale_days * 86_400) active = Legion::Data::Model::DigitalWorker.where(lifecycle_state: 'active') active.all.select do |w| w.last_heartbeat_at.nil? || w.last_heartbeat_at < cutoff end end |
.find(worker_id:) ⇒ Object
26 27 28 |
# File 'lib/legion/digital_worker.rb', line 26 def find(worker_id:) Legion::Data::Model::DigitalWorker.first(worker_id: worker_id) end |
.find_by_entra_app(entra_app_id:) ⇒ Object
30 31 32 |
# File 'lib/legion/digital_worker.rb', line 30 def find_by_entra_app(entra_app_id:) Legion::Data::Model::DigitalWorker.first(entra_app_id: entra_app_id) end |
.heartbeat(worker_id:, health_status: 'healthy', health_node: nil) ⇒ Object
46 47 48 49 50 51 52 53 54 |
# File 'lib/legion/digital_worker.rb', line 46 def heartbeat(worker_id:, health_status: 'healthy', health_node: nil) worker = Legion::Data::Model::DigitalWorker.first(worker_id: worker_id) return nil unless worker updates = { last_heartbeat_at: Time.now.utc, health_status: health_status } updates[:health_node] = health_node if health_node worker.update(updates) worker end |
.pause_orphans!(stale_days: 7, by: 'system:orphan_detection') ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/legion/digital_worker.rb', line 64 def pause_orphans!(stale_days: 7, by: 'system:orphan_detection') orphans = detect_orphans(stale_days: stale_days) orphans.each do |worker| Lifecycle.transition!( worker, to_state: 'paused', by: by, reason: "no heartbeat for #{stale_days}+ days", authority_verified: true ) if defined?(Legion::Events) Legion::Events.emit('worker.orphan_detected', { worker_id: worker.worker_id, owner_msid: worker.owner_msid, last_heartbeat_at: worker.last_heartbeat_at, at: Time.now.utc }) end rescue Lifecycle::InvalidTransition => e Legion::Logging.debug("[OrphanDetection] skip #{worker.worker_id}: #{e.}") if defined?(Legion::Logging) end orphans end |
.register(name:, extension_name:, entra_app_id:, owner_msid:, **opts) ⇒ Object
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/legion/digital_worker.rb', line 8 def register(name:, extension_name:, entra_app_id:, owner_msid:, **opts) Legion::Data::Model::DigitalWorker.create( worker_id: SecureRandom.uuid, name: name, extension_name: extension_name, entra_app_id: entra_app_id, owner_msid: owner_msid, owner_name: opts[:owner_name], business_role: opts[:business_role], risk_tier: opts[:risk_tier], team: opts[:team], manager_msid: opts[:manager_msid], lifecycle_state: 'bootstrap', consent_tier: 'supervised', trust_score: 0.0 ) end |