Merge pull request #51 from HackSoftware/add-note-about-circular-imports

Add subsection for circular import issues between tasks & services
This commit is contained in:
Radoslav Georgiev 2020-10-18 19:18:29 +03:00 committed by GitHub
commit d3fbe72bcb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -47,6 +47,7 @@ If you want to check an existing project showing most of the styleguide, [check
* [Structure](#structure) * [Structure](#structure)
+ [Configuration](#configuration) + [Configuration](#configuration)
+ [Tasks](#tasks) + [Tasks](#tasks)
+ [Circular imports between tasks & services](#circular-imports-between-tasks--services)
* [Periodic Tasks](#periodic-tasks) * [Periodic Tasks](#periodic-tasks)
* [Configuration](#configuration-1) * [Configuration](#configuration-1)
- [Misc](#misc) - [Misc](#misc)
@ -1179,6 +1180,69 @@ Meaning, you can end up with `tasks/domain_a.py` and `tasks/domain_b.py`. All yo
The general rule of thumb is - split your tasks in a way that'll make sense to you. The general rule of thumb is - split your tasks in a way that'll make sense to you.
#### Circular imports between tasks & services
In some cases, you need invoke a task from a service or vice-versa:
```python
# project/app/services.py
from project.app.tasks import task_function_1
def service_function_1():
print('I delay a task!')
task_function_1.delay()
def service_function_2():
print('I do not delay a task!')
```
```python
# project/app/tasks.py
from celery import shared_task
from project.app.services import service_function_2
@shared_task
def task_function_1():
print('I do not call a service!')
@shared_task
def task_function_2():
print('I call a service!')
service_function_2()
```
Unfortunately, this will result in a circular import.
What we usually do is we import the service function **inside** the task function:
```python
# project/app/tasks.py
from celery import shared_task
@shared_task
def task_function_1():
print('I do not call a service!')
@shared_task
def task_function_2():
from project.app.services import service_function_2 # <--
print('I call a service!')
service_function_2()
```
* Note: Depending on the case, you may want to import the task function **inside** the service function. This is OK and will still prevent the circular import between service & task functions.
### Periodic Tasks ### Periodic Tasks
Managing periodic tasks is quite important, especially when you have tens, or hundreds of them. Managing periodic tasks is quite important, especially when you have tens, or hundreds of them.