Background processes¶
Many workflows provide a convenient interface to applications and/or web services.
For performance reasons, it’s common for workflows to cache data locally, but updating this cache typically takes a few seconds, making your workflow unresponsive while an update is occurring, which is very un-Alfred-like.
To avoid such delays, Alfred-PyWorkflow provides the background
module to allow you to easily run scripts in the background.
There are two functions, run_in_background()
and is_running()
,
that provide the main interface. The processes started are full daemon
processes, so you can start real servers as easily as simple scripts.
Here’s an example of a common usage pattern (updating cached data in the background). What we’re doing is:
Checking the age of the cached data and running the update script via
run_in_background()
if the cached data are too old or don’t exist.(Optionally) informing the user that data are being updated.
Loading the cached data regardless of age.
Displaying the cached data (if any).
1 from workflow import Workflow, ICON_INFO
2 from workflow.background import run_in_background, is_running
3
4 def main(wf):
5 # Is cache over 1 hour old or non-existent?
6 if not wf.cached_data_fresh('exchange-rates', 3600):
7 run_in_background('update',
8 ['/usr/bin/env', 'python3',
9 wf.workflowfile('update_exchange_rates.py')])
10
11 if is_running('update'):
12 # Tell Alfred to run the script again every 0.5 seconds
13 # until the `update` job is complete (and Alfred is
14 # showing results based on the newly-retrieved data)
15 wf.rerun = 0.5
16 # Add a notification if the script is running
17 wf.add_item('Updating exchange rates...', icon=ICON_INFO)
18
19 # max_age=0 will load any cached data regardless of age
20 exchange_rates = wf.cached_data('exchage-rates', max_age=0)
21
22 # Display (possibly stale) cache data
23 if exchange_rates:
24 for rate in exchange_rates:
25 wf.add_item(rate)
26
27 # Send results to Alfred
28 wf.send_feedback()
29
30 if __name__ == '__main__':
31 # Use Workflow so we can use Alfred 3's awesome `rerun` feature
32 wf = Workflow()
33 wf.run(main)
For a working example, see Part 2 of the Tutorial or the source code of my Git Repos workflow, which is a bit smarter about showing the user update information.