BleuBizarre
BleuBizarre

Reputation: 378

Django-q2 schedule task hook on class function

I have an object as such :

class TestApp(models.Model):
    cron = models.CharField(max_length=200)
    args = models.CharField(max_length=200)
    test_function = models.ForeignKey(TestFunction, on_delete=models.CASCADE)
    scheduled_task = models.ForeignKey(Schedule, blank=True, null=True, on_delete=models.SET_NULL)

    def get_args(self):
        return ast.literal_eval(self.args)

    def run_function(self):
        Module = __import__(self.test_function.library_name)
        func = getattr(Module, self.test_function.function_name)
        result = func(*self.get_args())
        print(result)
        return result

    def print_task(self, task):
        print(self.id, task)

I am interested in having a schedule task as such :

def save(self, *args, **kwargs):
    self.scheduled_task = Schedule.objects.create(
        func=self.run_function,
        hook=self.print_task,
        schedule_type=Schedule.CRON,
        cron=self.cron
    )
    super(TestApp, self).save(*args, **kwargs)

But this does not work and will result something as :

18:32:02 [Q] INFO Process-f625bf1f4a024df8be5e15647bf294a9 created task alaska-ten-october-mirror from schedule [4]
18:32:02 [Q] INFO Process-069b6ca530ae4e83be6aedbd669a94a7 processing alaska-ten-october-mirror '<bound method TestApp.run_function of <TestApp: TestApp object (1)>>' [4]
18:32:02 [Q] ERROR malformed return hook '<bound method TestApp.print_task of <TestApp: TestApp object (1)>>' for [alaska-ten-october-mirror]
18:32:02 [Q] ERROR Failed '<bound method TestApp.run_function of <TestApp: TestApp object (1)>>' (alaska-ten-october-mirror) - Function <bound method TestApp.run_function of <TestApp: TestApp object (1)>> is not defined : Traceback (most recent call last):

When if I do a simple async call, it works :

def save(self, *args, **kwargs):
    async_task(
        func=self.run_function,
        hook=self.print_task
    )
    super(TestApp, self).save(*args, **kwargs)

This will properly do the work :

18:35:25 [Q] INFO Process-cfc73b4a7c5d48d69eed82b311f18250 processing ceiling-echo-six-west '<bound method TestApp.run_function of <TestApp: TestApp object (1)>>'
-2.0
1 ceiling-echo-six-west

I am not sure why the async can do it but not the schedule.

Upvotes: 0

Views: 289

Answers (1)

BleuBizarre
BleuBizarre

Reputation: 378

I guess it's because a schedule task needs to be able to run independantly of the other items but the issue above is because :

  • A task can have a reference function as function and hook
  • A schedule needs to have functions setup as "Dotted strings only."

How to do a workaround :

def save(self, *args, **kwargs):
    self.scheduled_task = Schedule.objects.create(
        func='test_app.tasks.run_function',
        hook='test_app.tasks.print_task',
        schedule_type=Schedule.CRON,
        cron=self.cron,
        kwargs={'TestApp_id': self.id}
    )
    super(TestApp, self).save(*args, **kwargs)

And then in your tasks.py I defined the tasks as such :

def run_function(**kwargs):
    id = kwargs['TestApp_id']
    test_app = TestApp.objects.get(pk=id)
    Module = __import__(test_app.test_function.library_name)
    func = getattr(Module, test_app.test_function.function_name)
    result = func(*test_app.get_args())
    print(result)
    return {
        'result': result,
        'TestApp_id': id
    }


def print_task(task):
    print(task.result['TestApp_id'], task.result['result'])

Upvotes: 0

Related Questions