Package gofer
[hide private]
[frames] | no frames]

Source Code for Package gofer

  1  # 
  2  # Copyright (c) 2011 Red Hat, Inc. 
  3  # 
  4  # This software is licensed to you under the GNU Lesser General Public 
  5  # License as published by the Free Software Foundation; either version 
  6  # 2 of the License (LGPLv2) or (at your option) any later version. 
  7  # There is NO WARRANTY for this software, express or implied, 
  8  # including the implied warranties of MERCHANTABILITY, 
  9  # NON-INFRINGEMENT, or FITNESS FOR A PARTICULAR PURPOSE. You should 
 10  # have received a copy of LGPLv2 along with this software; if not, see 
 11  # http://www.gnu.org/licenses/old-licenses/lgpl-2.0.txt. 
 12  # 
 13  # Jeff Ortel <jortel@redhat.com> 
 14  # 
 15   
 16  from threading import RLock 
 17   
 18   
 19  # process name used to build the following paths: 
 20  #   /etc/<NAME> 
 21  #   /etc/<NAME>/agent.conf 
 22  #   /etc/<NAME>/conf.d 
 23  #   /etc/<NAME>/plugins 
 24  #   /var/lib/<NAME> 
 25  #   /var/lib/<NAME>/messaging 
 26  #   /var/lib/<NAME>/journal 
 27  #   /usr/lib/<NAME>/<plugin> 
 28  #   /var/run/<NAME>d.pid 
 29  #   /var/log/<NAME>/agent.log 
 30  #   ~/.<NAME>/agent.conf 
 31  NAME = 'gofer' 
32 33 34 -class Singleton(type):
35 """ 36 Singleton metaclass 37 usage: __metaclass__ = Singleton 38 """ 39 40 __inst = {} 41 __mutex = RLock() 42 43 @classmethod
44 - def reset(cls):
45 cls.__inst = {}
46 47 @classmethod
48 - def key(cls, t, d):
49 key = [] 50 for x in t: 51 if isinstance(x, (str,int,float)): 52 key.append(x) 53 for k in sorted(d.keys()): 54 v = d[k] 55 if isinstance(v, (str,int,float)): 56 key.append((k,v)) 57 return repr(key)
58 59 @classmethod
60 - def all(cls):
61 cls.__lock() 62 try: 63 return cls.__inst.values() 64 finally: 65 cls.__unlock()
66
67 - def __call__(cls, *args, **kwargs):
68 cls.__lock() 69 try: 70 key = (cls.__name__, 71 cls.key(args, kwargs)) 72 inst = cls.__inst.get(key) 73 if inst is None: 74 inst = type.__call__(cls, *args, **kwargs) 75 cls.__inst[key] = inst 76 return inst 77 finally: 78 cls.__unlock()
79 80 @classmethod
81 - def __len__(cls):
82 cls.__lock() 83 try: 84 return len(cls.__inst) 85 finally: 86 cls.__unlock()
87 88 @classmethod
89 - def __lock(cls):
90 cls.__mutex.acquire()
91 92 @classmethod
93 - def __unlock(cls):
94 cls.__mutex.release()
95
96 97 -def synchronized(fn):
98 """ 99 Decorator that provides reentrant method invocation 100 using the object's mutex. The object must have a private 101 RLock attribute named __mutex. Intended only for instance 102 methods that have a method body that can be safely mutexed 103 in it's entirety to prevent deadlock senarios. 104 """ 105 def sfn(*args, **kwargs): 106 inst = args[0] 107 cn = inst.__class__.__name__ 108 mutex = getattr(inst, '_%s__mutex' % cn) 109 mutex.acquire() 110 try: 111 return fn(*args, **kwargs) 112 finally: 113 mutex.release()
114 return sfn 115
116 -def conditional(fn):
117 """ 118 Decorator that provides reentrant method invocation 119 using the object's mutex. The object must have a private 120 RLock attribute named __mutex. Intended only for instance 121 methods that have a method body that can be safely mutexed 122 in it's entirety to prevent deadlock senarios. 123 """ 124 def sfn(*args, **kwargs): 125 inst = args[0] 126 cn = inst.__class__.__name__ 127 mutex = getattr(inst, '_%s__condition' % cn) 128 mutex.acquire() 129 try: 130 return fn(*args, **kwargs) 131 finally: 132 mutex.release()
133 return sfn 134