Event Loops/Threads
The assistant needs separate event threads that repeatedly calls some functions every pre-determined amount of seconds so that much more can be done than what is already possible. Implementation details described below.
1. Primary Event Loop
A parallel-run, precise-to-second (by default) timer thread for the execution of functions or checks at every interval. Response engines like the Skill Based Response Engine can take advantage of this loop to for example, run code for passive skills in the background.
This loop calls the assistant.mainloop.tick()
function every second (by default, can be adjusted in config.toml
) which executes all the functions in mainloop.funcs[]
consecutively. The time delay between each tick could also be called the 'tickrate' as it is kind of the equivalent of the heartbeat of the assistant.
Ticker Class
A component class that plugs into the assistant just like interpreter or the memory components.
assistant.mainloop = EventLoop(self.config['developer']['main_loop_delay'])
assistant.mainloop.start()
Once activated, functions can be added to the main loop (from a response engine for example).
assistant.mainloop.add_function(function, args, kwargs)
Where function
is the function to run at each interval with specified arguments and keyword-arguments if any.
2. Scheduler Event Loop
Another parallel-run, precise-to-second (by default) timer thread for the execution of single-use functions at specified times. For example, if a task needs be scheduled to run at 5:00 A.M just once, it should be registered on the scheduler.
This loop calls the assistant.scheduler.tick()
function every second (by default, can be adjusted in config.toml
) which runs a check to see if the time has passed for any scheduled events in the queue (scheduler.queue[]
), and if it did, run them and dispose them from the queue.
Scheduler Class
A component class that plugs into the assistant like the ticker class.
assistant.scheduler = Scheduler(self.config['developer']['sched_loop_delay'])
assistant.scheduler.start()
Once activated, events can be added to the scheduler queue (from a response handler, for example)
assistant.scheduler.queue_event(function, time)
Where function
is the function to run at scheduled time
which should be a unix timestamp.
3. Update Event
The main thread used by the assistant also fires an assistant.on_update()
method everytime the assistant receives an input or gives an output. This event method should not be relied on for most use cases as it would only execute when the user is actively interacting with the assistant. It's better for things like auto-save or to maybe do some calculations, etc..
There are currently no plans to allow interpreters, handlers, or engines to add functions to the on_update()
event dynamically. In order to add things to this event, you would need to inherit the Assistant class and override the on_update()
method but be sure to call super().on_update()
first as well.