From 63022eee1a01dee21158744fddc743456fb77ca4 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Fri, 10 May 2024 16:34:28 +0100 Subject: [PATCH] Bootstrap some initial slides --- public/ridiculous.png | Bin 0 -> 23285 bytes public/soon.png | Bin 0 -> 10802 bytes slides.md | 460 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 460 insertions(+) create mode 100644 public/ridiculous.png create mode 100644 public/soon.png diff --git a/public/ridiculous.png b/public/ridiculous.png new file mode 100644 index 0000000000000000000000000000000000000000..9d31caf008a7df030e43eea4cc44e954ef23eef7 GIT binary patch literal 23285 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 Nkm`DB_Yqfb{1=b#E*}5@ literal 0 HcmV?d00001 diff --git a/slides.md b/slides.md index 901f29e..4ab064f 100644 --- a/slides.md +++ b/slides.md @@ -24,3 +24,463 @@ themeConfig:
  • @RealOrangeOne
  • @jake@theorangeone.net
  • + +--- +layout: center +--- + +# Django isn't _just_ for websites + + +```mermaid +flowchart LR + U(User 🧑‍💻) + D[\Django/] + + U---->|Request|D + D---->|Response|U +``` + + + +--- +layout: full +--- + +```mermaid +flowchart BT + U[User 🧑‍💻] + D[\Django/] + DB[(Database)] + C[(Cache)] + E>Email] + EA[External API] + V[[Video Transcode]] + ML((Machine Learning)) + + U---->|Request|D + D---->|Response|U + + D-.-DB & E & EA & V & ML & C +``` + +--- +layout: full +--- + +```mermaid +flowchart BT + U[User 🧑‍💻] + D[\Django/] + DB[(Database)] + C[(Cache)] + E>Email] + EA[External API] + V[[Video Transcode]] + ML((Machine Learning)) + B{{Background Processing}} + + U--->|Request|D + D--->|Response|U + + D---B + + D-.-C & DB + + B---E & V & ML & EA + B---C & DB +``` + +--- +layout: cover +--- + +# Background Workers? + +--- +layout: fact +--- + +```mermaid +flowchart LR + D[\Django/] + S[(Queue Store)] + R1{Runner} + R2{Runner} + R3{Runner} + + D<--->S<-..->R1 & R2 & R3 +``` + +--- +layout: cover +--- + +# When? + +--- +layout: fact +--- + + + +```mermaid +flowchart BT + D[\Django/] + + subgraph Fast & Reliable + DB[(Database)] + C[(Cache)] + end + + subgraph Slow / Unreliable + E>Email] + EA[External API] + V[[Video Transcode]] + ML((Machine Learning)) + end + + D---DB & C + + D-.-E & EA & V & ML +``` + +--- +layout: cover +--- + +# Background Workers _in Django_ + +--- +layout: cover +background: https://docs.celeryq.dev/en/stable/_static/celery_512.png +--- + +# Celery! + + + +--- +layout: image-right +image: https://images.unsplash.com/photo-1444703686981-a3abbc4d4fe3?q=80&w=1740&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D +--- + +# Others... + + + +- ~~Celery~~ +- arq +- Django DB Queue +- Django Lightweight Queue +- Django Too Simple Q +- Django-Q +- Django-Q2 +- Dramatiq +- Huey +- RQ +- Taskiq +- ... + + + +--- +layout: cover +background: https://images.unsplash.com/photo-1522096823084-2d1aa8411c13?q=80&w=1740&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D +--- + +# Email + +--- +layout: none +--- + +```python {all|8|9-14|16-19|all} +from django.contrib.auth.models import User +from django.core.mail import send_mail +from django.template.loader import render_to_string + +import django_rq + +def send_email_to_user(user: User): + email_content = render_to_string("email-template.html", {"user": user}) + send_mail( + subject="Here is your important customized message", + message=email_content + from_email=None, # Use the default sender email + recipient_list=[user.email] + ) + +users_to_email = User.objects.all() + +for user in users_to_email.iterator(): + django_rq.enqueue(send_email_to_user, user) +``` + + + +--- +layout: center +--- + +# A problem + +````md magic-move +```python +from django.contrib.auth.models import User +from django.core.mail import send_mail +from django.template.loader import render_to_string + +import django_rq + +def send_email_to_user(user: User): + email_content = render_to_string("email-template.html", {"user": user}) + send_mail( + subject="Here is your important customized message", + message=email_content + from_email=None, # Use the default sender email + recipient_list=[user.email] + ) + +users_to_email = User.objects.all() + +for user in users_to_email.iterator(): + django_rq.enqueue(send_email_to_user, user) +``` + +```python {all|5-7,20|all} +from django.contrib.auth.models import User +from django.core.mail import send_mail +from django.template.loader import render_to_string + +from my_celery_config import app + +@app.task +def send_email_to_user(user: User): + email_content = render_to_string("email-template.html", {"user": user}) + send_mail( + subject="Here is your important customized message", + message=email_content + from_email=None, # Use the default sender email + recipient_list=[user.email] + ) + +users_to_email = User.objects.all() + +for user in users_to_email.iterator(): + send_email_to_user.delay(user) +``` +```` + +--- +layout: fact +--- + +# Situation: +## There are _14_ competing standards. + + + +--- +layout: image-right +image: https://images.unsplash.com/photo-1674027444485-cec3da58eef4?q=80&w=1932&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D +class: flex items-center text-2xl +--- + +- Application developers +- Library maintainers +- System Engineers + +--- +layout: image +image: /ridiculous.png +class: bg-top! +--- + +# Ridiculous! + +--- +layout: fact +--- + +## Introducing:{.mb-5} + +# `django.tasks` + +--- +layout: center +--- + +````md magic-move +```python +from django.contrib.auth.models import User +from django.core.mail import send_mail +from django.template.loader import render_to_string + +from my_celery_config import app + +@app.task +def send_email_to_user(user: User): + email_content = render_to_string("email-template.html", {"user": user}) + send_mail( + subject="Here is your important customized message", + message=email_content + from_email=None, # Use the default sender email + recipient_list=[user.email] + ) + +users_to_email = User.objects.all() + +for user in users_to_email.iterator(): + send_email_to_user.delay(user) +``` + +```python {all|5-7,20|all} +from django.contrib.auth.models import User +from django.core.mail import send_mail +from django.template.loader import render_to_string + +from django.tasks import task + +@task() +def send_email_to_user(user: User): + email_content = render_to_string("email-template.html", {"user": user}) + send_mail( + subject="Here is your important customized message", + message=email_content + from_email=None, # Use the default sender email + recipient_list=[user.email] + ) + +users_to_email = User.objects.all() + +for user in users_to_email.iterator(): + send_email_to_user.enqueue(user) +``` +```` + +--- +layout: center +--- + +```python +from django.contrib.auth.models import User +from django.core.mail import send_mail +from django.template.loader import render_to_string + +users_to_email = User.objects.all() + +email_content = render_to_string("email-template.html") + +for user in users_to_email.iterator(): + send_mail( + subject="Here is your important message", + message=email_content + from_email=None, # Use the default sender email + recipient_list=[user.email] + ) +``` + + + +```python +# settings.py +EMAIL_BACKEND = "django.core.mail.backends.tasks.SMTPEmailBackend" +``` + + + + +--- +layout: image-right +image: /soon.png +class: flex justify-center text-2xl flex-col +--- + +# Q: Why something new? + + + +### A: We're not + + + +--- +layout: center +--- + +# Why something built-in? + + + + +- Reduces barrier to entry +- Improve interoperability +- Reduce cognitive load + + + + +--- +layout: section +--- + +# Where are we now? + + + +## `pip install django-tasks` + + + +--- +layout: section +--- + +# Where are we going? + +--- +layout: image-right +image: https://images.unsplash.com/photo-1451187580459-43490279c0fa?q=80&w=1744&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D +class: flex justify-center flex-col text-xl +--- + +# Out of scope + +- Completion / failed hooks +- Bulk queueing +- Automated task retrying +- Task runner API +- Unified observability +- Cron-based scheduling +- Task timeouts +- Swappable argument serialization + +--- +layout: section +--- + +# What's next? + +--- +layout: end +---