-1

This is in the context of refreshing an access token for a user. Say we have the function refresh_user_token that takes in a CustomUser object as user.

def refresh_user_token(user):
    ...
    ...
    return result

I'd like for each execution of this function for a specific CustomUser to schedule a repeat in 9 days.

def refresh_user_token(user):
    ...
    ...
    next_refresh = datetime.now() + timedelta(days=9)
    schedule_refresh(user, scheduled_time=next_refresh)
    return result

Most use cases I see for Celery are in regards to performing batch operations, but for this use I need to be able to execute the function with arguments which doesn't seem to be feasible with Celery.


Someone did recommend setting up a cron job to check for any tokens that need refreshed very x seconds.

So on the CustomUser object, we have a DateTimeField called last_token_refresh.

@Celery.task
def refresh_auth_tokens():
    users = CustomUser.objects.all()
    for user in users:
        last_refresh_delta = datetime.now(timezone.utc) - user.last_token_refresh
        if last_refresh_delta.days >= 9:
            refresh_user_token(user)
            return True
        else:
            return False

This could work, but I feel its very taxing when a message broker could be used to only schedule the tasks needed.

CodeSpent
  • 1,684
  • 4
  • 23
  • 46

1 Answers1

-1

You can use Celery Beat to schedule celery tasks using crontabs. Just create your regular Celery tasks and use Beat to say when to run.

This is a sample of a Celery Beat setup I have on a project:

CELERY_BEAT_SCHEDULE = {
    'populate_controller': {
        'task': 'common.tasks.populate_controller',
        # Will be executed Mondays, at 08:30 
        'schedule': crontab(day_of_week=2, 
                            hour=8, 
                            minute=30),
    'options': {'queue': 'populate_controller'}
    },
 }
Stargazer
  • 1,442
  • 12
  • 19
  • This doesn't address the issue. The issue is that I want to be able to schedule the task for specific users and varying times. 9 days after each execution for that user specifically. – CodeSpent Mar 29 '19 at 17:26
  • You can achieve that by tweaking your tasks with queries to find the user you want work on. Just setup the cron task and think on a proper way to find the user you need to update. Setup the cron to run everyday and update all the users you need to update on that given day querying users that were updated 9 days ago. – Stargazer Mar 29 '19 at 17:30
  • You'll notice in my question that I mentioned that exact solution and I'm looking for an alternative as I don't feel that's appropriate or scalable. – CodeSpent Mar 29 '19 at 17:31
  • Well, if you find a better way to deal with periodic tasks without recurring to schedules, let everybody know. – Stargazer Mar 29 '19 at 17:34
  • Rather than iterating through my entire user base to see who has not been refreshed every few seconds, a more elegant solution would be to use a message broker to schedule a job for a user. That way I'm only running jobs when they need to be run, not using resources just to check. – CodeSpent Mar 29 '19 at 17:39
  • Why would you iterate through all your base? That is basic SQL, to just get what you want. – Stargazer Mar 29 '19 at 17:41