Made model policies a threaded run loop, and made policy executions transactional
Sapan Bhatia [Fri, 23 Jan 2015 16:09:28 +0000 (16:09 +0000)]
planetstack/model_policy.py

index 7aef793..8ddb82e 100644 (file)
@@ -1,11 +1,14 @@
 from django.db.models.signals import post_save
 from django.dispatch import receiver
 import pdb
-from core.models import *
 from dependency_walker import *
 import model_policies
 from util.logger import logger
-
+from datetime import datetime
+import time
+from core.models import *
+from django.db.transaction import atomic
+from django.db.models import F, Q
 
 modelPolicyEnabled = True
 
@@ -22,40 +25,48 @@ def update_dep(d, o):
        
 def delete_if_inactive(d, o):
        #print "Deleting %s (%s)"%(d,d.__class__.__name__)
-       d.delete()      
+       # d.delete()    
        return
 
-def execute_model_policy(policy_name, instance, update_fields_empty, deleted):
-       if (update_fields_empty):
-               # Automatic dirtying
-               #walk_inv_deps(update_dep, instance)
+@atomic
+def execute_model_policy(instance, deleted):
+       # Automatic dirtying
+       walk_inv_deps(update_dep, instance)
 
+       sender_name = instance.__class__.__name__
+       policy_name = 'model_policy_%s'%sender_name
+       noargs = False
+
+       if deleted:
+               walk_inv_deps(delete_if_inactive, instance)
+       else:
                try:
                        policy_handler = getattr(model_policies, policy_name, None)
-                        logger.error("POLICY HANDLER: %s %s" % (policy_name, policy_handler))                       
+                       logger.error("POLICY HANDLER: %s %s" % (policy_name, policy_handler))                       
                        if policy_handler is not None:
                                policy_handler.handle(instance)
                except:
                        logger.log_exc("Model Policy Error:") 
                        print "Policy Exceution Error"
-       elif deleted:
-               walk_inv_deps(delete_if_inactive, instance)
-
 
-@receiver(post_save)
-def post_save_handler(sender, instance, **kwargs):
-        if not modelPolicyEnabled:
-            return
+       instance.policed=datetime.now()
+        instance.save(update_fields=['policed'])
 
-       sender_name = sender.__name__
-       policy_name = 'model_policy_%s'%sender_name
-        if (not kwargs['update_fields']):
-               noargs = True
-               deleted = False
-       else:
-               noargs = False
-               deleted = True
+def run_policy():
+        from core.models import Slice,Controller,Network,User,SlicePrivilege,Site,SitePrivilege,Image,ControllerSlice
+       while (True):
+               start = time.time()
+               models = [Slice, Controller, Network, User, SlicePrivilege, Site, SitePrivilege, Image, ControllerSlice]
+               objects = []
+               
+               for m in models:
+                       res = m.objects.filter(Q(policed__lt=F('updated')) | Q(policed=None))
+                       objects.extend(res)     
 
-       execute_model_policy(policy_name, instance, noargs, deleted)
-       
-       
+               for o in objects:
+                       print "Working on %r"%o
+                       execute_model_policy(o, False)
+               
+               
+               if (time.time()-start<1):
+                       time.sleep(1)