2013-01-16 8 views
6

To może być pytanie python. Bez wątpienia jest to noobish.django wstępnie oblicza i buforuje widok

Klient żąda strony wymagającej dużych obliczeń [strona-1] i ostatecznie zażąda drugiej strony wymagającej dużych obliczeń [strona-2], którą można obliczyć na przykład, gdy znane jest żądanie dla strony-1. Nie chcę obliczyć każdego zestawu danych przed udostępnieniem strony-1, ponieważ znacznie spowolni to działanie początkowej odpowiedzi.

Chcę obliczyć wartość dla strony-2, podczas gdy klient czyta stronę-1. Klient może również kliknąć kilka przycisków, które powodują odpowiedź, która zapewnia inny widok danych na stronie 1, ale nie wymagają intensywnego obliczania. W końcu, ale niekoniecznie natychmiast, klient poprosi o stronę 2 i chcę mieć możliwość odpowiedzi z wcześniej wyświetloną odpowiedzią.

Jak to zrobić?

+0

którą chcesz wywołać funkcja asynchroniczna, która oblicza stronę 2 na podstawie informacji o stronie 1, przechowuje ją w pamięci podręcznej (lub w dowolnym miejscu), a następnie na stronie 2: stale odpytuje widok, który wie, aby sprawdzić określony klucz w pamięci podręcznej, aby określić, kiedy zadanie w tle zostało zakończone obliczanie zadania step2. –

+0

Nie mam pojęcia, jak to zrobić. Każde małe przewodnictwo bardzo by pomogło. – Cole

+1

Przykro mi, nie mogę przejść do bardziej szczegółowych informacji bez pisania eseju. Zasadniczo musisz wywołać tę kosztowną funkcję, gdy tylko klient1 przeczyta stronę. Jeśli nie chcesz, aby klient oczekiwał na to przed załadowaniem strony, musisz uczynić to zadanie asynchronicznym. Zadanie w tle. Następnie na stronie 2 należy uwzględnić fakt, że zadanie w tle NIE jest jeszcze ukończone. W związku z tym twoja druga strona musi mieć mechanizm, aby nieprzerwanie odpytywać serwer do czasu zakończenia zadania BG, po czym możesz pokazać stronę 2 swojemu użytkownikowi. –

Odpowiedz

7

Jak wspomniano w komentarzach, wygląda na to, że zajmiemy się tym z asynchronicznym zadaniem w tle, zapisując wynik w Django low level cache. Osobiście użyłbym celery dla kolejki zadań.

Zasadniczo po zgłoszeniu pierwszej strony należy dodać asynchroniczne zadanie, aby rozpocząć obliczenia strony 2, przechowując wynik w pamięci podręcznej. Tak więc, gdy zażąda się strony 2, sprawdzasz wstępnie renderowaną odpowiedź w pamięci podręcznej, a jeśli ona nie istnieje, możesz obliczyć wartość synchronicznie.

Tak Twój kod będzie wyglądać mniej więcej tak (zadanie byłoby w pliku task.py w swojej aplikacji, ale to powinno dać ogólne pojęcie):

from celery import task 
from django.core.cache import cache 

def page_two_calculation(arg1, arg2): 
    return arg1 + arg2 

@task 
def page_two_task(arg1, arg2): 
    result = page_two_calculation(arg1, arg2) 
    cache_key = "page-two-%s-%s" (arg1, arg2) 
    cache.set(cache_key, result) 

def page_one(request, arg1, arg2): 

    # Start the page two task 
    page_two_task.delay(arg1, arg2) 

    # Return the page one response 
    return HttpResponse('page one') 

def page_two(request, arg1, arg2) 
    cache_key = "page-two-%s-%s" (arg1, arg2) 
    result = cache.get(cache_key) 
    if result is None: 
     # the result will only be None if the page 2 calculation 
     # doesn't exist in the cache, in which case we'll have to 
     # return the value synchronously. 
     result = page_two_calculation(arg1, arg2) 
    return result 
Powiązane problemy