11<!-- License Badge -->
22[ ![ License] ( https://img.shields.io/badge/License-Apache_2.0-blue.svg )] ( https://github.com/ansible/dispatcher/blob/main/LICENSE )
33
4- This is intended to be a working space for prototyping a code split of:
5-
6- < https://github.com/ansible/awx/tree/devel/awx/main/dispatch >
4+ ## Dispatcher
75
8- As a part of doing the split, we also want to resolve a number of
9- long-standing design and sustainability issues, thus, asyncio.
10-
11- The philosophy of the dispatcher is to have a limited scope
6+ The dispatcher is a service to run python tasks in subprocesses,
7+ designed specifically to work well with pg_notify,
8+ but intended to be extensible to other message delivery means.
9+ Its philosophy is to have a limited scope
1210as a "local" runner of background tasks, but to be composable
1311so that it can be "wrapped" easily to enable clustering and
1412distributed task management by apps using it.
1513
14+ > [ !WARNING]
15+ > This project is in initial development. Expect many changes, including name, paths, and CLIs.
16+
1617Licensed under [ Apache Software License 2.0] ( LICENSE )
1718
1819### Usage
1920
2021You have a postgres server configured and a python project.
2122You will use dispatcher to trigger a background task over pg_notify.
22-
2323Both your * background dispatcher service* and your * task publisher* process must have
24- python configured so that your task is importable.
24+ python configured so that your task is importable. Instructions are broken into 3 steps:
25+
26+ 1 . ** Library** - Configure dispatcher, mark the python methods you will run with it
27+ 2 . ** Dispatcher service** - Start your background task service, it will start listening
28+ 3 . ** Publisher** - From some other script, submit tasks to be ran
2529
26- For more options, see ` docs/usage.md ` .
30+ In the "Manual Demo" section, an runnable example of this is given .
2731
2832#### Library
2933
3034The dispatcher ` @task() ` decorator is used to register tasks.
3135
32- See the ` tools/test_methods.py ` module.
33- This defines a dispatcher task and the pg_notify channel it will be sent over.
36+ The [ tests/data/methods.py] ( tests/data/methods.py ) module defines some
37+ dispatcher tasks and the pg_notify channels they will be sent over.
38+ For more ` @task ` options, see [ docs/task_options.md] ( docs/task_options.md ) .
3439
3540``` python
3641from dispatcher.publish import task
@@ -49,10 +54,12 @@ from dispatcher.config import setup
4954config = {
5055 " producers" : {
5156 " brokers" : {
52- " pg_notify" : {" conninfo" : " dbname=postgres user=postgres" },
53- " channels" : [
54- " test_channel" ,
55- ],
57+ " pg_notify" : {
58+ " conninfo" : " dbname=postgres user=postgres"
59+ " channels" : [
60+ " test_channel" ,
61+ ],
62+ },
5663 },
5764 },
5865 " pool" : {" max_workers" : 4 },
@@ -62,6 +69,8 @@ setup(config)
6269
6370For more on how to set up and the allowed options in the config,
6471see the section [ config] ( docs/config.md ) docs.
72+ The ` queue ` passed to ` @task ` needs to match a pg_notify channel in the ` config ` .
73+ It is often useful to have different workers listen to different sets of channels.
6574
6675#### Dispatcher service
6776
@@ -83,8 +92,8 @@ run_service()
8392```
8493
8594Configuration tells how to connect to postgres, and what channel(s) to listen to.
86- The demo has this in ` dispatcher.yml ` , which includes listening to ` test_channel ` .
87- That matches the ` @task ` in the library.
95+
96+
8897
8998#### Publisher
9099
@@ -116,38 +125,64 @@ print_hello.apply_async(args=[], kwargs={})
116125The difference is that ` apply_async ` takes both args and kwargs as kwargs themselves,
117126and allows for additional configuration parameters to come after those.
118127
119- As of writing, this only works if you have a Django connection configured.
120- You can manually pass configuration info (as in the demo) for non-Django use.
121-
122128### Manual Demo
123129
130+ For this demo, the [ tests/data/methods.py] ( tests/data/methods.py ) will be used
131+ in place of a real app. Making those importable is why ` PYTHONPATH ` must be
132+ modified in some steps. The config for this demo can be found in the
133+ [ dispatcher.yml] ( dispatcher.yml ) file, which is a default location
134+ the ` dispatcher-standalone ` entrypoint looks for.
135+
136+ Initial setup:
137+
138+ ```
139+ pip install -e .[pg_notify]
140+ make postgres
141+ ```
142+
124143You need to have 2 terminal tabs open to run this.
125144
126145```
127146# tab 1
128- make postgres
129- PYTHONPATH=$PYTHONPATH:tools/ dispatcher-standalone
147+ PYTHONPATH=$PYTHONPATH:. dispatcher-standalone
130148# tab 2
131- python tools/write_messages .py
149+ ./run_demo .py
132150```
133151
134- This will run the dispatcher with schedules, and process a burst of messages
135- that give instructions to run tasks.
152+ This will run the dispatcher with schedules, and process bursts of messages
153+ that give instructions to run tasks. Tab 2 will contain some responses
154+ from the dispatcher service. Tab 1 will show a large volume of logs
155+ related to processing tasks.
136156
137157### Running Tests
138158
139- A structure has been set up for integration tests.
140- The word "integration" only means that postgres must be running.
159+ Most tests (except for tests/unit/) require postgres to be running.
141160
142161```
143162pip install -r requirements_dev.txt
144163make postgres
145- py.test tests/
164+ pytest tests/
146165```
147166
148- This accomplishes the most basic of starting and shutting down.
149- With no tasks submitted, it should record running 0 tasks,
150- and with a task submitted, it records running 1 task.
167+ ### Background
168+
169+ This is intended to be a working space for prototyping a code split of:
170+
171+ < https://github.com/ansible/awx/tree/devel/awx/main/dispatch >
172+
173+ As a part of doing the split, we also want to resolve a number of
174+ long-standing design and sustainability issues, thus, asyncio.
175+ For a little more background see [ docs/design_notes.md] ( docs/design_notes.md ) .
176+
177+ There is documentation of the message formats used by the dispatcher
178+ in [ docs/message_formats.md] ( docs/message_formats.md ) . Some of these are internal,
179+ but some messages are what goes over the user-defined brokers (pg_notify).
180+ You can trigger tasks using your own "publisher" code as an alternative
181+ to attached methods like ` .apply_async ` . Doing this requires connecting
182+ to postges and submitting a pg_notify message with JSON data
183+ that conforms to the expected format.
184+ The ` ./run_demo.py ` script shows examples of this, but borrows some
185+ connection and config utilities to help.
151186
152187## Contributing
153188
0 commit comments