D
D
Denis Usanov2014-10-18 01:27:07
Python
Denis Usanov, 2014-10-18 01:27:07

How to execute pending tasks on the backend?

In almost every web service where there is user registration and some kind of their state, such a task exists. For example, "gold" status, premium status. The user pays money, his status changes, the end date is set: in a month, a year. The question is how to see that the time has elapsed and return the user to a normal state. I gave only an example, you can come up with others.
So, right off the bat, I can come up with two solutions:

  1. Write a separate daemon that once every n times checks the list of tasks (or the expiration date of gold status from my example) and changes the states
  2. Same as cron daemon

How are these issues usually handled? Would a task queue like Celery work?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
A
Anatoly Scherbakov, 2014-10-18
@Altaisoft

An alternative approach is to not store the current user status at all. Instead, keep a log of changes to this status and calculate its current value on demand. I am accustomed to talk in terms of Django, and we will focus on its ORM. Let's say you have your own model for the user - User in my_auth application . Let it have two status values: empty ( None ) and premium - for those who paid for a yearly subscription. Status change log:

from django.db import models
from my_auth.models import User

class StatusEvent(models.Model):
    EVENT_TYPES = [
        ('subscription', 'User subscribed to premium')
    ]
    user = models.ForeignKey(User, related_name='events')
    time = models.DateTimeField(auto_now_add=True)
    type = models.CharField(max_length=16, choices=EVENT_TYPES)

    class Meta:
        ordering = '-time'

The status calculation function is defined in the User model :
from datetime import datetime
from django.contrib.auth.models import User as DefaultUser

class User(DefaultUser):
    @property
    def status(self):
        event = self.events.filter(type='subscription').first()
        if event and datetime.now() - event.time < self.subscription_duration:
            return 'premium'

Here subscription_duration is the duration of the subscription, a value of type datetime.timedelta . Well, or relativedelta from dateutil can be used, it is more convenient. Yes, this entails constant status checks, but I don't think it's that much of a problem compared to having another cron or Celery process thrashing around, making the system unnecessarily complex.

W
WebSpider, 2014-10-18
@WebSpider

What's wrong with cron? In my opinion the most appropriate solution in this situation

I
Ivan, 2014-10-18
@LiguidCool

To be honest, I don't know how they do it "in the best houses...", but I just cron'd wget php of the page that contained the necessary code.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question