Skip to content

Using Celery, just do instance.call_delay('method_name', *args, **kwargs).

Notifications You must be signed in to change notification settings

bryanhelmig/django-delay-method

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 

Repository files navigation

django-method-delay

This is a simple way to use Celery without writing your own tasks for models. This makes it super, duper easy to port an existing legacy app to async. All you have to do is...

from delay_method.models import DelayedMethodModel

class YourModel(DelayedMethodModel)
    # ...

...and...

instance.call_delay('method_name', *args, **kwargs)

A demo is worth a thousand words...

Your models.py....

from django.db import models

from delay_method.models import DelayedMethodModel


class Person(DelayedMethodModel):
    added = models.DateTimeField(auto_now_add=True)
    
    name = models.CharField(max_length=100)
    skill = models.CharField(max_length=255)

    friends = models.ManyToManyField('self')
    
    def together(self):
        return '{0} is great at {1}.'.format(self.name, self.skill)
    
    def likes(self, *args):
        return '{0} likes {1}.'.format(self.name, ', '.join(args))
    
    def puts(self, **kwargs):
        puts = ' and '.join(
            ['the {0} in the {1}'.format(k,v) for k,v in kwargs.items()]
        )
        return '{0} puts {1}.'.format(self.name, puts)

    def alert_friends(self):
        for friend in self.friends.all():
            # send an email!
            pass

Your view.py....

from django.http import HttpResponse

from myapp.models import Person


def combine_view(request, person_id):
    """
    Collecting multiple slow to compute things to return to the
    user at the same time.
    """
    person = Person.objects.get(id=person_id)
    
    # equivalent to person.together()
    task1 = person.call_delay('together')
    
    # equivalent to person.likes('cats', 'dogs)
    task2 = person.call_delay('likes', 'cats', 'dogs')
    
    # equivalent to person.puts(dog='doghouse', cat='litter box')
    task3 = person.call_delay('puts', dog='doghouse', cat='litter box')
    
    # you'd need to collect the results....
    together, likes, puts = task1.wait(), task2.wait(), task3.wait()
    
    return HttpResponse("\n".join([together, likes, puts]))


def trigger_view(request, person_id):
    """
    Let this persons friends know something is up. We don't want to call
    person.alert_friends() directly in the request/response cycle as that 
    would be very slow to make the view wait on maybe hundreds of emails
    being sent. 
    """
    person = Person.objects.get(id=person_id)
    
    # equivalent to person.alert_friends()
    task = person.call_delay('alert_friends')
    
    return HttpResponse('Your friends will be alerted!')

About

Using Celery, just do instance.call_delay('method_name', *args, **kwargs).

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages