Threading
Configuration
Property |
Default |
Description |
|---|---|---|
|
True |
Whether to pin apps to threads |
|
None |
The total number of threads to create, defaults to the number of active apps. |
|
None |
The number (out of the total) of threads to reserve for pinning; only used by |
Thread Creation
Threads are created during startup in
create_initial_threads().User-configured values are resolved into actual numbers using
resolve_thread_counts().Threads all have an ID number (0 - <
appdaemon.total_threads>)Some of them are reserved for pinned callbacks (0 - <
appdaemon.pin_threads>)The remaining are free for unpinned callbacks
AppDaemon will assign a
pin_threadto an app when it’s created, ifpin_app=Trueandpin_thread=None.Must be configured in file or have global setting to
pin_app=Falseto not get an assigned thread.
Pin behavior and thread assignments are stored in
ManagedObjectattributes
Thread Pinning
These settings get passed around through the AppDaemon internals and ultimately determine which thread handles a callback.
Setting |
Description |
|---|---|
|
Whether the app should be pinned to a single thread. |
|
The thread the app is pinned to. This determines which thread the callback gets run in |
Level |
Description |
|---|---|
Global |
The global settings are set in the |
Per App |
The pinning behavior for apps can be changed at runtime. The current settings are stored in the corresponding |
Per Callback |
The pinning behavior for a specific callback can be overridden at registration. |
App gets created by the app manager
App object and settings are stored in the
ManagedObjectpin_appis set from the config file, defaulting to global settingpin_threadcould be set from the config file, but could be assigned by AD at that point
App runs and maybe the
pin_apporpin_threadgets changed at some point.Any changes affect the settings in
ManagedObject
Callback could also override either
pin_apporpin_threadpin_appshould be calculated at callback registrationIf the callback specifies a
pin_threadthat impliespin_app=True, otherwise thepin_threadwill get ignored inselect_qIf
pin_appends up being True, but there’s nopin_threadassigned, one needs to be assigned at call time - will be 0.If
pin_appis False,pin_threadwill get ignored at call time
Callback lives in internal dicts
pin_appis neverNonepin_threadcould beNone- load distribution should be calculated at call time.
pin_appandpin_threadmake their way through the internals, eventually toThreading.select_qselect_qhinges onpin_appbeing True/False.pin_appis neverNoneIf
pin_appis not True,pin_threadis ignored, and the thread is automatically chosen according to the load distribution setting
Config Precedence
Callback-level pin: Top-level override
App-level pin: Acts as the default for each callback as it’s created.
Config-level pin (default): Acts as the default when the app manager creates a new
ManagedObject
Default Case
By default, a new thread will be created for each active app, and each app will get pinned to its own thread.
Default (initial case)
Global:
pin_apps=TrueApp:
pin_app=None
Each app has a
ManagedObjectinstance that holds thepin_appandpin_threadsettings for that app.When an app is created
pin_app=Truegets set (from the global default) andpin_threadgets assigned.The
pin_appandpin_threadsettings for an app can be altered in theManagedObjectduring runtime.The
pin_appandpin_threadsettings can be provided during callback registration to override the settings for that callback only.
Callback Registration
The determine_thread() method is used during callback registration to resolve pin_app for that callback.
Callback Type |
Registration |
Processing |
|---|---|---|
Schedule |
|
|
Event |
||
State |
|
|
Log |
Reference
- class appdaemon.threads.Threading(ad: AppDaemon)
Subsystem container for managing
Threadobjects- async add_thread(silent: bool = False, id: int | None = None) None
Create a new worker thread.
This is where the Thread object is actually created and started. The thread will begin running the worker method as its target, and a new entity will be added to the thread domain in the admin namespace to track it.
- determine_thread(name: str, cb_pin: bool | None, cb_pin_thread: int | None) tuple[bool, int | None]
Determine pin settings for a callback using inputs from the callback registration with settings from the app management as defaults.
If the callback thread is not specified, then which thread it gets called in should be calculated at call time to get good results from the different load distribution strategies. The length of the various thread queues can be wildly different at call time from when the callback was first registered.
- Dev Note:
This method is a good place to handle things related to thread/pinning at callback registration.