from django.http import HttpResponse from django.shortcuts import render_to_response as show_page from django.conf import settings from datetime import datetime , timedelta from threading import Thread import time __all__ = [ 'StatefulView' , 'Page' , 'FinalPage' , 'show_page' ] class Page ( HttpResponse ): pass class FinalPage ( HttpResponse ): pass class StatefulViewType ( type ): def __init__ ( cls , name , bases , dct ): LIVING_STATES = {} cls . _LIVING_STATES = LIVING_STATES delta = timedelta ( seconds = settings . CLEAN_STATES_SECONDS ) def clean_threads (): while True : for k ,( s , updated ) in LIVING_STATES . items (): if updated + delta < datetime . today (): try : del LIVING_STATES [ k ] except KeyError : pass time . sleep ( settings . CLEAN_STATES_SECONDS ) t = Thread ( target = clean_threads ) t . daemon = True t . start () class StatefulView ( object ): __metaclass__ = StatefulViewType @classmethod def handle ( cls , request , * a , ** kw ): keyname = str ( cls ) + '_' + request . session . session_key states = cls . _LIVING_STATES if keyname in states : gen , x = states [ keyname ] response = gen . send (( request , a , kw )) else : gen = cls () . main () response = gen . next () if isinstance ( response , FinalPage ): del states [ keyname ] else : states [ keyname ] = ( gen , datetime . now ()) return response def main ( self , request , * a , ** kw ): raise NotImplementedError ( " %s must implement 'main'" % self . __class__ . __name__ )