c8d3e4289986cfe4d380cf72660a5126ab155620
[plstackapi.git] / planetstack / observer / syncstep.py
1 import os
2 import base64
3 from planetstack.config import Config
4
5 class FailedDependency(Exception):
6     pass
7
8 class SyncStep:
9     """ A PlanetStack Sync step. 
10
11     Attributes:
12         psmodel        Model name the step synchronizes 
13         dependencies    list of names of models that must be synchronized first if the current model depends on them
14     """ 
15     slow=False
16     def get_prop(prop):
17         try:
18             sync_config_dir = Config().sync_config_dir
19         except:
20             sync_config_dir = '/etc/planetstack/sync'
21         prop_config_path = '/'.join(sync_config_dir,self.name,prop)
22         return open(prop_config_path).read().rstrip()
23
24     def __init__(self, **args):
25         """Initialize a sync step
26            Keyword arguments:
27                    name -- Name of the step
28                 provides -- PlanetStack models sync'd by this step
29         """
30         dependencies = []
31         self.driver = args.get('driver')
32         try:
33             self.soft_deadline = int(self.get_prop('soft_deadline_seconds'))
34         except:
35             self.soft_deadline = 5 # 5 seconds
36
37         return
38
39     def fetch_pending(self):
40         return Sliver.objects.filter(ip=None)
41     
42     def check_dependencies(self, obj):
43         for dep in self.dependencies:
44             peer_object = getattr(obj, dep.name.lowercase())
45             if (peer_object.pk==dep.pk):
46                 raise DependencyFailed
47
48     def call(self, failed=[]):
49         pending = self.fetch_pending()
50         for o in pending:
51             if (not self.depends_on(o, failed)):
52                 try:
53                     check_dependencies(o) # Raises exception if failed                    
54                     self.sync_record(o)
55                     o.enacted = datetime.now() # Is this the same timezone? XXX
56                     o.save(update_fields=['enacted'])
57                 except:
58                     failed.append(o)
59         return failed
60
61     def __call__(self):
62         return self.call()