Class: Insika::HarvestEngine
- Inherits:
-
Object
- Object
- Insika::HarvestEngine
- Defined in:
- lib/insika/harvest_engine.rb
Overview
the trigger — finds due sessions and mines them. It
spawns a worker fiber (supervisor child, Tick#start shape) whose loop
claims a window and runs ONE due session's harvest ON the worker fiber —
off the tick's critical path and off every customer turn's path (D2: the
mining model call never blocks a customer turn).
The scan uses the engine default idle_hours (24) as the LOWER BOUND; the
per-agent value is re-checked inside RunHarvest. The loop-stop (the
H-harvest kill) is the profile's enabled: false — the engine only
respects data (D4).
Constant Summary collapse
- SCOPE =
"harvest_engine"- KEY =
"claim"- DEFAULT_WINDOW =
seconds — the O(n) scan never rides the 60 s loop
300- DEFAULT_IDLE_HOURS =
24- DEFAULT_MIN_MESSAGES =
3
Instance Attribute Summary collapse
-
#runner ⇒ Object
The deployment root swaps in its own runner (the bus instance carrying the negative list + the settings-backed miner factory); the base graph's inert one keeps the loop honest until then.
Instance Method Summary collapse
-
#initialize(store:, harvest_store:, session_store:, runner:, profiles: nil, logger: nil, window: DEFAULT_WINDOW, idle_hours: DEFAULT_IDLE_HOURS, sleeper: nil) ⇒ HarvestEngine
constructor
A new instance of HarvestEngine.
-
#run_once ⇒ Object
One pass.
-
#start(parent:) ⇒ Object
The supervisor child (tick.rb:69-83's shape).
Constructor Details
#initialize(store:, harvest_store:, session_store:, runner:, profiles: nil, logger: nil, window: DEFAULT_WINDOW, idle_hours: DEFAULT_IDLE_HOURS, sleeper: nil) ⇒ HarvestEngine
Returns a new instance of HarvestEngine.
23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/insika/harvest_engine.rb', line 23 def initialize(store:, harvest_store:, session_store:, runner:, profiles: nil, logger: nil, window: DEFAULT_WINDOW, idle_hours: DEFAULT_IDLE_HOURS, sleeper: nil) @store = store @harvest_store = harvest_store @session_store = session_store @runner = runner @profiles = profiles # profile source; nil/empty = nothing mines (parity) @logger = logger @window = window.to_i @idle_hours = idle_hours.to_i @sleeper = sleeper || method(:default_sleep) end |
Instance Attribute Details
#runner ⇒ Object
The deployment root swaps in its own runner (the bus instance carrying the negative list + the settings-backed miner factory); the base graph's inert one keeps the loop honest until then.
40 41 42 |
# File 'lib/insika/harvest_engine.rb', line 40 def runner @runner end |
Instance Method Details
#run_once ⇒ Object
One pass. -> { claimed: false } | { claimed: true, mined: N, skipped: N, errors: N }
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/insika/harvest_engine.rb', line 63 def run_once return { claimed: false } unless harvestable? return { claimed: false } unless claim_window session = due_sessions.first # one model call per pass; the window paces return { claimed: true, mined: 0, skipped: 0, errors: 0 } if session.nil? begin outcome = @runner.call(Insika::Command.build(:run_harvest, { agent: session[:agent], session_ids: [session[:id]] })) if outcome[:mined] { claimed: true, mined: 1, skipped: 0, errors: 0 } else { claimed: true, mined: 0, skipped: 1, errors: 0 } end rescue StandardError # a broken session must not hold the pass; the marker discipline # keeps it re-runnable. { claimed: true, mined: 0, skipped: 0, errors: 1 } end end |
#start(parent:) ⇒ Object
The supervisor child (tick.rb:69-83's shape). Returns false when idle_hours <= 0 (the engine default OFF switch — parity) OR when no profile declares an enabled harvest (a scan with nothing to mine would re-read every session record every window forever).
46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/insika/harvest_engine.rb', line 46 def start(parent:) return false unless harvestable? @task = parent.async do |t| t.annotate("insika-harvest") loop do @sleeper.call(@window) run_once rescue StandardError => e log(:warn, "harvest pass failed: #{e.class}: #{e.}") end end true end |