Monday, 7 November 2022

Django / celery mult thread

 django async :

https://docs.djangoproject.com/en/4.1/topics/async/


python thread library:

https://docs.python.org/3/library/threading.html


down side for python threading for web app is that 1 user sends a request, multi threads run, server has to wait for desired thread to finish to give response.


Task based threading :

http request send, server immidately responbds. multi thread jobs are then ran in the background.

Faster response, more complex setup, acheived through celery:


https://medium.com/@ravisarath64/are-you-working-on-django-is-celery-confuse-you-629fedf8287b



User sends request
Django receives => spawns a thread to do something else.
wait for the main thread to finishes & the other thread to finishes after completion of both tasks
response is sent to the user as a package 😭 --> it takes too much time.
User sends request
Django receives => lets Celery know "hey! do this!"
main thread finishes
response is sent to the user
The user receives the balance of the transaction 😄 --> it's so fast
Django says => Celery starts a task A.Django says => Celery starts a task B.Django says => Celery starts a task C.at some point Celery says =>  Wait for A to finish
User sends request
Django receives => Celery send an email at midnight for the user.
main thread finishes
the response is sent to the user
User sends request
Django receives => Celery sent alert to the user in every 10 min.
main thread finishes
the response is sent to the user
pip install celery
BROKER_URL = 'redis://localhost:6379'
from __future__ import absolute_import
import os
from celery import Celery
from django.conf import settings

# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
app = Celery('picha')

# Using a string here means the worker will not have to
# pickle the object when using Windows.
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
# If you need to schedule a task or run a task periodically you can # add this code app.conf.beat_schedule = {
# to run a task daily at 12.30 AM midnight 'generate_daily_settlement_report’: {
'task’: 'app.tasks.function_A’,
'schedule’: crontab(hour=1, minute=30),
},
# to run a task in every 30 seconds
'add-every-30-seconds’: {
'task’: 'app.tasks.function_B’,
'schedule’: 30.0,
'args’: (16, 16)
},
}
@app.task(bind=True)
def debug_task(self):
print('Request: {0!r}'.format(self.request))
from celery.decorators import task

@task(name="function A")
def function_A():
'''do something '''
@task(name="function B")
def function_B():
'''do something '''
@task(name="function C")
def function_C():
'''do something '''
function_C.delay()
celery -A tasks worker --loglevel=INFO
celery -A tasks beat --loglevel=INFO
  • Run your Django and Redis.
  • Open two new terminal windows/tabs.
  • In each new window, navigate to your project directory.
  • Activate your virtualenv.
  • Run the celery beat and worker commands.


No comments:

Post a Comment