Skip to content

Commit 3f3b18f

Browse files
committed
updates
1 parent 4cc6e83 commit 3f3b18f

File tree

9 files changed

+204
-3
lines changed

9 files changed

+204
-3
lines changed

docker-compose.yml

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,48 @@ services:
55
build: ./project
66
command: python manage.py runserver 0.0.0.0:8000
77
volumes:
8-
- ./project/:/usr/src/app/
8+
- ./project:/usr/src/app/
99
ports:
1010
- 1337:8000
1111
environment:
1212
- DEBUG=1
1313
- SECRET_KEY=dbaa1_i7%*3r9-=z-+_mz4r-!qeed@(-a_r(g@k8jo8y3r27%m
1414
- DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1]
15+
- CELERY_BROKER=redis://redis:6379/0
16+
- CELERY_BACKEND=redis://redis:6379/0
17+
depends_on:
18+
- redis
19+
20+
celery:
21+
build: ./project
22+
command: celery --app=core worker --loglevel=info --logfile=logs/celery.log
23+
volumes:
24+
- ./project:/usr/src/app
25+
environment:
26+
- DEBUG=1
27+
- SECRET_KEY=dbaa1_i7%*3r9-=z-+_mz4r-!qeed@(-a_r(g@k8jo8y3r27%m
28+
- DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1]
29+
- CELERY_BROKER=redis://redis:6379/0
30+
- CELERY_BACKEND=redis://redis:6379/0
31+
depends_on:
32+
- web
33+
- redis
34+
35+
redis:
36+
image: redis:7-alpine
37+
38+
dashboard:
39+
build: ./project
40+
command: celery flower -A core --port=5555 --broker=redis://redis:6379/0
41+
ports:
42+
- 5555:5555
43+
environment:
44+
- DEBUG=1
45+
- SECRET_KEY=dbaa1_i7%*3r9-=z-+_mz4r-!qeed@(-a_r(g@k8jo8y3r27%m
46+
- DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1]
47+
- CELERY_BROKER=redis://redis:6379/0
48+
- CELERY_BACKEND=redis://redis:6379/0
49+
depends_on:
50+
- web
51+
- redis
52+
- celery

project/core/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from .celery import app as celery_app
2+
3+
4+
__all__ = ("celery_app",)

project/core/celery.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import os
2+
3+
from celery import Celery
4+
5+
6+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "core.settings")
7+
app = Celery("core")
8+
app.config_from_object("django.conf:settings", namespace="CELERY")
9+
app.autodiscover_tasks()

project/core/settings.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,6 @@
125125
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
126126

127127
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
128+
129+
CELERY_BROKER_URL = os.environ.get("CELERY_BROKER", "redis://redis:6379/0")
130+
CELERY_RESULT_BACKEND = os.environ.get("CELERY_BROKER", "redis://redis:6379/0")

project/logs/celery.log

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
[2022-12-21 16:47:49,082: INFO/MainProcess] Connected to redis://redis:6379/0
2+
[2022-12-21 16:47:49,086: INFO/MainProcess] mingle: searching for neighbors
3+
[2022-12-21 16:47:50,096: INFO/MainProcess] mingle: all alone
4+
[2022-12-21 16:47:50,115: WARNING/MainProcess] /usr/local/lib/python3.11/site-packages/celery/fixups/django.py:203: UserWarning: Using settings.DEBUG leads to a memory
5+
leak, never use this setting in production environments!
6+
warnings.warn('''Using settings.DEBUG leads to a memory
7+
8+
[2022-12-21 16:47:50,116: INFO/MainProcess] celery@0b19cf0c09bb ready.
9+
[2022-12-21 16:48:45,436: INFO/MainProcess] Task tasks.sample_tasks.create_task[635a1fa3-02a1-41cf-abf0-42e0127b3765] received
10+
[2022-12-21 16:48:55,456: INFO/ForkPoolWorker-7] Task tasks.sample_tasks.create_task[635a1fa3-02a1-41cf-abf0-42e0127b3765] succeeded in 10.01617115503177s: True
11+
[2022-12-21 16:51:01,846: INFO/MainProcess] Connected to redis://redis:6379/0
12+
[2022-12-21 16:51:01,849: INFO/MainProcess] mingle: searching for neighbors
13+
[2022-12-21 16:51:02,861: INFO/MainProcess] mingle: all alone
14+
[2022-12-21 16:51:02,878: WARNING/MainProcess] /usr/local/lib/python3.11/site-packages/celery/fixups/django.py:203: UserWarning: Using settings.DEBUG leads to a memory
15+
leak, never use this setting in production environments!
16+
warnings.warn('''Using settings.DEBUG leads to a memory
17+
18+
[2022-12-21 16:51:02,880: INFO/MainProcess] celery@2e3daf621da5 ready.
19+
[2022-12-21 16:51:05,949: INFO/MainProcess] Events of group {task} enabled by remote.
20+
[2022-12-21 16:56:02,981: INFO/MainProcess] Task tasks.sample_tasks.create_task[152a015a-6630-4274-b8d2-10c4ffecf14a] received
21+
[2022-12-21 16:56:03,329: INFO/MainProcess] Task tasks.sample_tasks.create_task[61ddae5c-4db6-494c-b7fe-e2ec91c0e014] received
22+
[2022-12-21 16:56:03,720: INFO/MainProcess] Task tasks.sample_tasks.create_task[382e2ad5-1145-4294-8b59-ede3be06c72f] received
23+
[2022-12-21 16:56:04,223: INFO/MainProcess] Task tasks.sample_tasks.create_task[6f09bb48-9fbb-47bc-839d-6d5514297562] received
24+
[2022-12-21 16:56:04,377: INFO/MainProcess] Task tasks.sample_tasks.create_task[771216dc-a9c8-48ad-b9d0-e2b4c8afb3b9] received
25+
[2022-12-21 16:56:12,990: INFO/ForkPoolWorker-7] Task tasks.sample_tasks.create_task[152a015a-6630-4274-b8d2-10c4ffecf14a] succeeded in 10.006136342999525s: True
26+
[2022-12-21 16:56:14,232: INFO/ForkPoolWorker-2] Task tasks.sample_tasks.create_task[6f09bb48-9fbb-47bc-839d-6d5514297562] succeeded in 10.00528918299824s: True
27+
[2022-12-21 16:56:14,389: INFO/ForkPoolWorker-3] Task tasks.sample_tasks.create_task[771216dc-a9c8-48ad-b9d0-e2b4c8afb3b9] succeeded in 10.009019681951031s: True
28+
[2022-12-21 16:56:23,336: INFO/ForkPoolWorker-8] Task tasks.sample_tasks.create_task[61ddae5c-4db6-494c-b7fe-e2ec91c0e014] succeeded in 20.00379785092082s: True
29+
[2022-12-21 16:56:33,707: INFO/ForkPoolWorker-1] Task tasks.sample_tasks.create_task[382e2ad5-1145-4294-8b59-ede3be06c72f] succeeded in 30.004541549948044s: True
30+
[2022-12-21 16:56:43,150: INFO/MainProcess] Connected to redis://redis:6379/0
31+
[2022-12-21 16:56:43,156: INFO/MainProcess] mingle: searching for neighbors
32+
[2022-12-21 16:56:43,166: INFO/MainProcess] Connected to redis://redis:6379/0
33+
[2022-12-21 16:56:43,169: INFO/MainProcess] Connected to redis://redis:6379/0
34+
[2022-12-21 16:56:43,172: INFO/MainProcess] mingle: searching for neighbors
35+
[2022-12-21 16:56:43,176: INFO/MainProcess] mingle: searching for neighbors
36+
[2022-12-21 16:56:44,171: INFO/MainProcess] mingle: all alone
37+
[2022-12-21 16:56:44,185: INFO/MainProcess] mingle: all alone
38+
[2022-12-21 16:56:44,187: INFO/MainProcess] mingle: all alone
39+
[2022-12-21 16:56:44,189: WARNING/MainProcess] /usr/local/lib/python3.11/site-packages/celery/fixups/django.py:203: UserWarning: Using settings.DEBUG leads to a memory
40+
leak, never use this setting in production environments!
41+
warnings.warn('''Using settings.DEBUG leads to a memory
42+
43+
[2022-12-21 16:56:44,190: INFO/MainProcess] celery@653ee816ebe2 ready.
44+
[2022-12-21 16:56:44,204: WARNING/MainProcess] /usr/local/lib/python3.11/site-packages/celery/fixups/django.py:203: UserWarning: Using settings.DEBUG leads to a memory
45+
leak, never use this setting in production environments!
46+
warnings.warn('''Using settings.DEBUG leads to a memory
47+
48+
[2022-12-21 16:56:44,204: WARNING/MainProcess] /usr/local/lib/python3.11/site-packages/celery/fixups/django.py:203: UserWarning: Using settings.DEBUG leads to a memory
49+
leak, never use this setting in production environments!
50+
warnings.warn('''Using settings.DEBUG leads to a memory
51+
52+
[2022-12-21 16:56:44,206: INFO/MainProcess] celery@b4ea1b210aeb ready.
53+
[2022-12-21 16:56:44,206: INFO/MainProcess] celery@63ec05680c0f ready.
54+
[2022-12-21 16:56:47,008: INFO/MainProcess] Events of group {task} enabled by remote.
55+
[2022-12-21 16:56:47,008: INFO/MainProcess] Events of group {task} enabled by remote.
56+
[2022-12-21 16:56:47,009: INFO/MainProcess] Events of group {task} enabled by remote.
57+
[2022-12-21 16:56:48,756: INFO/MainProcess] Task tasks.sample_tasks.create_task[5553d69f-39ba-4c51-aaf3-e4c0900ef1e9] received
58+
[2022-12-21 16:56:48,909: INFO/MainProcess] Task tasks.sample_tasks.create_task[d96a69a4-adc5-4209-a240-b91fdd746fc4] received
59+
[2022-12-21 16:56:49,109: INFO/MainProcess] Task tasks.sample_tasks.create_task[fda090c4-49e1-4eb6-bf1a-fa6b4ecd59fe] received
60+
[2022-12-21 16:56:49,274: INFO/MainProcess] Task tasks.sample_tasks.create_task[d21b53e8-be94-4c4f-9d0a-bb682650dad0] received
61+
[2022-12-21 16:56:49,808: INFO/MainProcess] Task tasks.sample_tasks.create_task[dfd05da9-61ae-494b-93e3-57bbede53349] received
62+
[2022-12-21 16:56:50,271: INFO/MainProcess] Task tasks.sample_tasks.create_task[78b4aad0-be1e-4a89-b4d5-846b767f486d] received
63+
[2022-12-21 16:56:50,656: INFO/MainProcess] Task tasks.sample_tasks.create_task[c866210a-51ac-487d-a5e4-8bf096ffe07a] received
64+
[2022-12-21 16:56:51,095: INFO/MainProcess] Task tasks.sample_tasks.create_task[c33b7654-7a9b-4962-b40b-bb990054b78c] received
65+
[2022-12-21 16:56:58,745: INFO/ForkPoolWorker-7] Task tasks.sample_tasks.create_task[5553d69f-39ba-4c51-aaf3-e4c0900ef1e9] succeeded in 10.00700472900644s: True
66+
[2022-12-21 16:56:58,896: INFO/ForkPoolWorker-7] Task tasks.sample_tasks.create_task[d96a69a4-adc5-4209-a240-b91fdd746fc4] succeeded in 10.005238652927801s: True
67+
[2022-12-21 16:56:59,097: INFO/ForkPoolWorker-7] Task tasks.sample_tasks.create_task[fda090c4-49e1-4eb6-bf1a-fa6b4ecd59fe] succeeded in 10.006078375969082s: True
68+
[2022-12-21 16:56:59,263: INFO/ForkPoolWorker-8] Task tasks.sample_tasks.create_task[d21b53e8-be94-4c4f-9d0a-bb682650dad0] succeeded in 10.006702068960294s: True
69+
[2022-12-21 16:57:01,082: INFO/ForkPoolWorker-8] Task tasks.sample_tasks.create_task[c33b7654-7a9b-4962-b40b-bb990054b78c] succeeded in 10.004813229083084s: True
70+
[2022-12-21 16:57:09,796: INFO/ForkPoolWorker-8] Task tasks.sample_tasks.create_task[dfd05da9-61ae-494b-93e3-57bbede53349] succeeded in 20.005408580997027s: True
71+
[2022-12-21 16:57:10,644: INFO/ForkPoolWorker-1] Task tasks.sample_tasks.create_task[c866210a-51ac-487d-a5e4-8bf096ffe07a] succeeded in 20.005450515076518s: True
72+
[2022-12-21 16:57:20,257: INFO/ForkPoolWorker-1] Task tasks.sample_tasks.create_task[78b4aad0-be1e-4a89-b4d5-846b767f486d] succeeded in 30.00418946298305s: True
73+
[2022-12-21 16:57:40,431: INFO/MainProcess] Connected to redis://redis:6379/0
74+
[2022-12-21 16:57:40,436: INFO/MainProcess] mingle: searching for neighbors
75+
[2022-12-21 16:57:41,447: INFO/MainProcess] mingle: all alone
76+
[2022-12-21 16:57:41,462: WARNING/MainProcess] /usr/local/lib/python3.11/site-packages/celery/fixups/django.py:203: UserWarning: Using settings.DEBUG leads to a memory
77+
leak, never use this setting in production environments!
78+
warnings.warn('''Using settings.DEBUG leads to a memory
79+
80+
[2022-12-21 16:57:41,463: INFO/MainProcess] celery@ccdf62931dfc ready.
81+
[2022-12-21 16:57:44,545: INFO/MainProcess] Events of group {task} enabled by remote.
82+
[2022-12-21 17:04:15,473: INFO/MainProcess] Task tasks.sample_tasks.create_task[e3bb9c95-9c55-4782-bcf2-9e3ebf1dd73e] received
83+
[2022-12-21 17:04:15,479: INFO/ForkPoolWorker-7] Task tasks.sample_tasks.create_task[e3bb9c95-9c55-4782-bcf2-9e3ebf1dd73e] succeeded in 0.0029084390262141824s: True

project/requirements.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
Django==4.1.4
22
pytest==7.2.0
33
pytest-django==4.5.2
4+
5+
celery==5.2.7
6+
redis==4.4.0
7+
flower==1.2.0

project/tasks/sample_tasks.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import time
2+
3+
from celery import shared_task
4+
5+
6+
@shared_task
7+
def create_task(task_type):
8+
time.sleep(int(task_type) * 10)
9+
return True

project/tasks/views.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
from celery.result import AsyncResult
12
from django.http import JsonResponse
23
from django.shortcuts import render
34
from django.views.decorators.csrf import csrf_exempt
45

6+
from tasks.sample_tasks import create_task
7+
58

69
def home(request):
710
return render(request, "home.html")
@@ -11,9 +14,16 @@ def home(request):
1114
def run_task(request):
1215
if request.POST:
1316
task_type = request.POST.get("type")
14-
return JsonResponse({"task_type": task_type}, status=202)
17+
task = create_task.delay(int(task_type))
18+
return JsonResponse({"task_id": task.id}, status=202)
1519

1620

1721
@csrf_exempt
1822
def get_status(request, task_id):
19-
return JsonResponse({"task_id": task_id}, status=200)
23+
task_result = AsyncResult(task_id)
24+
result = {
25+
"task_id": task_id,
26+
"task_status": task_result.status,
27+
"task_result": task_result.result
28+
}
29+
return JsonResponse(result, status=200)

project/tests/test_tasks.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,48 @@
1+
import json
2+
from unittest.mock import patch
3+
14
from django.urls import reverse
25

6+
from tasks import sample_tasks
7+
38

49
def test_home(client):
510
url = reverse("home")
611
response = client.get(url)
712
assert response.status_code == 200
13+
14+
15+
def test_task():
16+
assert sample_tasks.create_task.run(1)
17+
assert sample_tasks.create_task.run(2)
18+
assert sample_tasks.create_task.run(3)
19+
20+
21+
@patch("tasks.sample_tasks.create_task.run")
22+
def test_mock_task(mock_run):
23+
assert sample_tasks.create_task.run(1)
24+
sample_tasks.create_task.run.assert_called_once_with(1)
25+
26+
assert sample_tasks.create_task.run(2)
27+
assert sample_tasks.create_task.run.call_count == 2
28+
29+
assert sample_tasks.create_task.run(3)
30+
assert sample_tasks.create_task.run.call_count == 3
31+
32+
33+
def test_task_status(client):
34+
response = client.post(reverse("run_task"), {"type": 0})
35+
content = json.loads(response.content)
36+
task_id = content["task_id"]
37+
assert response.status_code == 202
38+
assert task_id
39+
40+
response = client.get(reverse("get_status", args=[task_id]))
41+
content = json.loads(response.content)
42+
assert content == {"task_id": task_id, "task_status": "PENDING", "task_result": None}
43+
assert response.status_code == 200
44+
45+
while content["task_status"] == "PENDING":
46+
response = client.get(reverse("get_status", args=[task_id]))
47+
content = json.loads(response.content)
48+
assert content == {"task_id": task_id, "task_status": "SUCCESS", "task_result": True}

0 commit comments

Comments
 (0)