Made model policies a threaded run loop, and made policy executions transactional
[plstackapi.git] / planetstack / model_policy.py
1 from django.db.models.signals import post_save
2 from django.dispatch import receiver
3 import pdb
4 from dependency_walker import *
5 import model_policies
6 from util.logger import logger
7 from datetime import datetime
8 import time
9 from core.models import *
10 from django.db.transaction import atomic
11 from django.db.models import F, Q
12
13 modelPolicyEnabled = True
14
15 def EnableModelPolicy(x):
16     global modelPolicyEnabled
17     modelPolicyEnabled = x
18
19 def update_dep(d, o):
20         try:
21                 if (d.updated < o.updated):
22                         d.save(update_fields=['updated'])
23         except AttributeError,e:
24                 raise e
25         
26 def delete_if_inactive(d, o):
27         #print "Deleting %s (%s)"%(d,d.__class__.__name__)
28         # d.delete()    
29         return
30
31 @atomic
32 def execute_model_policy(instance, deleted):
33         # Automatic dirtying
34         walk_inv_deps(update_dep, instance)
35
36         sender_name = instance.__class__.__name__
37         policy_name = 'model_policy_%s'%sender_name
38         noargs = False
39
40         if deleted:
41                 walk_inv_deps(delete_if_inactive, instance)
42         else:
43                 try:
44                         policy_handler = getattr(model_policies, policy_name, None)
45                         logger.error("POLICY HANDLER: %s %s" % (policy_name, policy_handler))                       
46                         if policy_handler is not None:
47                                 policy_handler.handle(instance)
48                 except:
49                         logger.log_exc("Model Policy Error:") 
50                         print "Policy Exceution Error"
51
52         instance.policed=datetime.now()
53         instance.save(update_fields=['policed'])
54
55 def run_policy():
56         from core.models import Slice,Controller,Network,User,SlicePrivilege,Site,SitePrivilege,Image,ControllerSlice
57         while (True):
58                 start = time.time()
59                 models = [Slice, Controller, Network, User, SlicePrivilege, Site, SitePrivilege, Image, ControllerSlice]
60                 objects = []
61                 
62                 for m in models:
63                         res = m.objects.filter(Q(policed__lt=F('updated')) | Q(policed=None))
64                         objects.extend(res)     
65
66                 for o in objects:
67                         print "Working on %r"%o
68                         execute_model_policy(o, False)
69                 
70                 
71                 if (time.time()-start<1):
72                         time.sleep(1)