diff --git a/.env.example b/.env.example index 0055875..052fb16 100644 --- a/.env.example +++ b/.env.example @@ -7,6 +7,9 @@ AUTH0_CLIENT_ID= AUTH0_CLIENT_SECRET= AUTH0_DOMAIN= +CELERY_BROKER_URL=redis://redis:6379/0 +CELERY_RESULT_BACKEND=redis://redis:6379/0 + DJANGO_HOST= DJANGO_SUPERUSER_EMAIL= DJANGO_SUPERUSER_USERNAME= diff --git a/docker-compose.yml b/docker-compose.yml index 4e36026..27b79d5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -64,6 +64,18 @@ services: networks: - apinet + redisinsight: + container_name: amui-redisinsight + image: redislabs/redisinsight:latest + ports: + - 5540:5540 + volumes: + - redisinsight_data:/data + networks: + - apinet + # extra_hosts: + # - "host.docker.internal:host-gateway" + pgadmin: container_name: amui-pgadmin image: dpage/pgadmin4 @@ -99,6 +111,7 @@ services: flow3d: container_name: amui-flow3d environment: + - CELERY_RESULT_BACKEND=${CELERY_RESULT_BACKEND} - QT_QPA_PLATFORM=minimal build: context: ./services/flow3d @@ -109,7 +122,7 @@ services: - REDHAT_USERNAME=${REDHAT_USERNAME} - REDHAT_PASSWORD=${REDHAT_PASSWORD} - # Uncomment for production + # Uncomment for non-development # command: bash ./entrypoint.sh tty: true depends_on: @@ -137,6 +150,7 @@ volumes: web_node_modules: flow3d_out: flow3d_venv: + redisinsight_data: networks: apinet: diff --git a/services/api/api/celery.py b/services/api/api/celery.py index 1fa87c6..a7d9c6d 100644 --- a/services/api/api/celery.py +++ b/services/api/api/celery.py @@ -15,7 +15,3 @@ # Load task modules from all registerd Django apps. app.autodiscover_tasks() - -@app.task(bind=True, ignore_result=True) -def debug_task(self): - print(f"Request: {self.request!r}") diff --git a/services/api/api/settings.py b/services/api/api/settings.py index 938ac53..fa81a7c 100644 --- a/services/api/api/settings.py +++ b/services/api/api/settings.py @@ -43,8 +43,8 @@ "django.contrib.staticfiles", # Third Party "corsheaders", - "django_filters", "django_extensions", + "django_filters", "rest_framework", # Apps "auth0", @@ -204,5 +204,8 @@ USE_X_FORWARDED_HOST = True # Celery -CELERY_BROKER_URL = 'redis://redis:6379/0' -CELERY_BROKER_BACKEND = 'redis://redis:6379/0' +CELERY_BROKER_URL = os.environ.get("CELERY_BROKER_URL") +CELERY_RESULT_BACKEND = os.environ.get("CELERY_RESULT_BACKEND") +CELERY_IGNORE_RESULT = False +CELERY_TRACK_STARTED = True +CELERY_TASK_IGNORE_RESULT = False diff --git a/services/api/flow3d/urls.py b/services/api/flow3d/urls.py index b1a12ac..35aec70 100644 --- a/services/api/flow3d/urls.py +++ b/services/api/flow3d/urls.py @@ -4,6 +4,7 @@ urlpatterns = [ path("flow3d/test_task/", views.Flow3DTestTask.as_view()), + path("flow3d/test_task//", views.Flow3DTestTask.as_view()), ] urlpatterns = format_suffix_patterns(urlpatterns) diff --git a/services/api/flow3d/views.py b/services/api/flow3d/views.py index c2153c8..46024da 100644 --- a/services/api/flow3d/views.py +++ b/services/api/flow3d/views.py @@ -8,6 +8,8 @@ # from flow3d.tasks import add from api.celery import app +import time + class Flow3DTestTask(APIView): permission_classes = (AllowAny,) @@ -17,5 +19,12 @@ def post(self, request): x = request.data.get("x") y = request.data.get("y") # add.delay(x, y) - app.send_task('flow3d.tasks.add', args=[x, y]) - return Response({"message": "task is processing"}, status=status.HTTP_201_CREATED) \ No newline at end of file + task = app.send_task('flow3d.tasks.add', args=[x, y]) + return Response({"task_id": task.id }, status=status.HTTP_201_CREATED) + + def get(self, request, task_id): + task_result = app.AsyncResult(task_id) + result = task_result.result + status = task_result.status + print(result, status) + return Response({"task_id": task_id, "status": status, "result": result}) diff --git a/services/flow3d/Dockerfile b/services/flow3d/Dockerfile index bdcbcae..0678d3b 100644 --- a/services/flow3d/Dockerfile +++ b/services/flow3d/Dockerfile @@ -102,8 +102,9 @@ COPY ./out ./out ################# # Celery Worker # ################# + COPY ./entrypoint.sh . -COPY ./flow3d ./flow3d +COPY ./worker ./worker # Runs 'entrypoint.sh' script. # https://stackoverflow.com/a/50276037/10521456 diff --git a/services/flow3d/entrypoint.sh b/services/flow3d/entrypoint.sh index 4cc7255..5d8a94c 100755 --- a/services/flow3d/entrypoint.sh +++ b/services/flow3d/entrypoint.sh @@ -5,4 +5,5 @@ echo "Starting Worker..." . venv/bin/activate cd worker -exec celery -A app worker --loglevel=info \ No newline at end of file + +exec celery -A app worker --loglevel=info --pool=solo -E diff --git a/services/flow3d/worker/app.py b/services/flow3d/worker/app.py index 3cd33c8..83b0516 100644 --- a/services/flow3d/worker/app.py +++ b/services/flow3d/worker/app.py @@ -2,6 +2,9 @@ app = Celery('app', broker='redis://redis:6379/0') +app.conf.task_track_started = True +app.conf.task_ignore_result = False + # Needed to discover tasks import flow3d diff --git a/services/web/src/flow3d/TestTaskForm.tsx b/services/web/src/flow3d/TestTaskForm.tsx index 512031b..cd7a6fa 100644 --- a/services/web/src/flow3d/TestTaskForm.tsx +++ b/services/web/src/flow3d/TestTaskForm.tsx @@ -8,7 +8,7 @@ import { Box, Button, TextField } from '@mui/material'; import { ChangeEvent, FC, useState } from 'react'; // API -import { postFlow3DTestTask } from './_api'; +import { getFlow3DTestTask, postFlow3DTestTask } from './_api'; interface Request { x: string; @@ -21,6 +21,8 @@ const TestTaskForm: FC = () => { y: '', }); + const [taskId, setTaskId] = useState('') + // Callbacks const handleChange = (e: ChangeEvent) => { const { name, value } = e.target; @@ -34,6 +36,10 @@ const TestTaskForm: FC = () => { await postFlow3DTestTask(request); }; + const handleClickTaskResult = async () => { + await getFlow3DTestTask(taskId); + }; + return ( { + setTaskId(e.target.value)} + value={taskId} + /> + ); }; diff --git a/services/web/src/flow3d/_api.ts b/services/web/src/flow3d/_api.ts index 9e9d6d6..4a3e5d9 100644 --- a/services/web/src/flow3d/_api.ts +++ b/services/web/src/flow3d/_api.ts @@ -21,3 +21,14 @@ export const postFlow3DTestTask = async (xy: XY) => { return null; } }; + +export const getFlow3DTestTask = async (task_id: string) => { + try { + const response = await axios.get(`flow3d/test_task/${task_id}/`); + const { data, status: code } = response; + return { data, code }; + } catch (error) { + console.log(error) + return null; + } +};