Skip to content

Instantly share code, notes, and snippets.

@jgram925
Last active June 15, 2019 17:52
Show Gist options
  • Save jgram925/7b48956cf38443b3326c8486ea3f778d to your computer and use it in GitHub Desktop.
Save jgram925/7b48956cf38443b3326c8486ea3f778d to your computer and use it in GitHub Desktop.
Celery Tasks & Ajax Polling.md

Django Celery Setup

Flower Celery Monitoring Utility Setup

This step is optional, but a nice way to keep the user informed. This button function notifies the user about the process and how to check the status. Then it will call the function below.

{{whatever_template_button_is_on}}.html

<script>
    $("#button_to_call_function).click(function(){
        var c = alert("Generic user notification of what will happen");
        window.location.href = "{% url 'call_function' %}";
    });
</script>



This fuction calls the Celery task function and creates a cookie with the Celery task id. If the cookie_value is nothing it adds it. Else it appends it to the string with a "|" seperator. The cookie will be used to track the Celery task status using ajax polling.

views.py

@login_required
def call_function(request):
    task = celery_task.delay()
    cookie_value = request.COOKIES.get('celery_task')   
    if not cookie_value:
        cookie_value = task.id
    else: 
        cookie_value = '|'.join([cookie_value, task.id])
    response = HttpResponse(status=204)   
    response.set_cookie('celery_task', cookie_value)
    return response



This is the task that Celery will perform. This function is initiated by call_function.

tasks.py

from celery import shared_task

@shared_task
def celery_task():
    # Do whatever!
    return results



This function gets the cookie and turns the string into a list, then into JSON. Ajax polling will use this JSON to check the Celery task status.

views.py

def celery_status(request):
    cookie_value = request.COOKIES.get('celery_task')
    cookie_list = cookie_value.split('|')
    results = []
    for x in cookie_list:
        celery_task_results = celery_all_grids.AsyncResult(x)
        task_id = x
        status = celery_task_results.status
        result = celery_task_results.result
        results.append({'task_id': task_id, 'status': status, 'result': result})
    return JsonResponse(results, safe=False)



A status page is create to use ajax polling to check the JSON status'. The ajax call retrieves the JSON and generates a table for each dictionary in the list. The setInterval function is used to check the JSON every 15 seconds.

NOTE: a condition for the setInterval should be set but haven't found a good method, yet.

{{celery_status_page}}.html

<table class="mws-table">
    <thead>
        <tr>
            <th>Status</th>
            <th>PDF</th>
            <th>Link</th>
        </tr>
    </thead>
    <tbody>
    </tbody>
</table>

<script>
$.getJSON( "/json/celery_all_grids_status/", function(data){
    $.each(data, function (index, item) {
        if(item.result != null){
            pdf_name = item.result.slice(17);
            url_link = item.result;
        } else{
            pdf_name = "Waiting for name!";
            url_link = "";
        }
        var eachrow = "<tr>"
                        + "<td>" + item.status + "</td>"
                        + "<td>" 
                            + pdf_name
                        + "</td>" 
                        + "<td>" 
                            + "<a href='" + url_link + "'>"
                                + "<i class='icol-application-go'></i>"
                            + "</a>" 
                        + "</td>" 
        $('tbody').append(eachrow);
    });
});
setInterval(function(){
    location.reload();
}, 15000);
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment