Back to index

moin  1.9.0~rc2
Public Member Functions | Private Member Functions | Private Attributes
MoinMoin.support.xappy.replaylog.ReplayLog Class Reference

List of all members.

Public Member Functions

def __init__
def log_call
def log_except
def log_retval

Private Member Functions

def _get_obj_num
def _is_xap_obj
def _get_xap_name
def _log
def _repr_arg
def _repr_args
def _get_call_id
def _obj_gone

Private Attributes

 _fd_mutex
 _fd
 _mutex
 _next_call
 _next_thread
 _thread_ids
 _objs
 _next_num
 _xapian_classes
 _xapian_functions
 _xapian_methods

Detailed Description

Log of xapian calls, to be replayed.

Definition at line 56 of file replaylog.py.


Constructor & Destructor Documentation

Create a new replay log.

Definition at line 61 of file replaylog.py.

00061 
00062     def __init__(self, logpath):
00063         """Create a new replay log.
00064 
00065         """
00066         # Mutex used to protect all access to _fd
00067         self._fd_mutex = threading.Lock()
00068         self._fd = file(logpath, 'wb')
00069 
00070         # Mutex used to protect all access to members other than _fd
00071         self._mutex = threading.Lock()
00072         self._next_call = 1
00073 
00074         self._next_thread = 0
00075         self._thread_ids = {}
00076 
00077         self._objs = weakref.WeakKeyDictionary()
00078         self._next_num = 1
00079 
00080         self._xapian_classes = {}
00081         self._xapian_functions = {}
00082         self._xapian_methods = {}
00083         for name in dir(xapian):
00084             item = getattr(xapian, name)
00085             has_members = False
00086             for membername in dir(item):
00087                 member = getattr(item, membername)
00088                 if isinstance(member, types.MethodType):
00089                     self._xapian_methods[member.im_func] = (name, membername)
00090                     has_members = True
00091             if has_members:
00092                 self._xapian_classes[item] = name
00093             if isinstance(item, types.BuiltinFunctionType):
00094                 self._xapian_functions[item] = name


Member Function Documentation

Get an ID string for a call.

The mutex should be held when this is called.

Definition at line 250 of file replaylog.py.

00250 
00251     def _get_call_id(self):
00252         """Get an ID string for a call.
00253 
00254         The mutex should be held when this is called.
00255 
00256         """
00257         call_num = self._next_call
00258         self._next_call += 1
00259 
00260         thread_id = thread.get_ident()
00261         try:
00262             thread_num = self._thread_ids[thread_id]
00263         except KeyError:
00264             thread_num = self._next_thread
00265             self._thread_ids[thread_id] = thread_num
00266             self._next_thread += 1
00267 
00268         if thread_num is 0:
00269             return "%s" % call_num
00270         return "%dT%d" % (call_num, thread_num)

Here is the caller graph for this function:

def MoinMoin.support.xappy.replaylog.ReplayLog._get_obj_num (   self,
  obj,
  maybe_new 
) [private]
Get the number associated with an object.

If maybe_new is False, a value of 0 will be supplied if the object
hasn't already been seen.  Otherwise, a new (and previously unused)
value will be allocated to the object.

The mutex should be held when this is called.

Definition at line 95 of file replaylog.py.

00095 
00096     def _get_obj_num(self, obj, maybe_new):
00097         """Get the number associated with an object.
00098 
00099         If maybe_new is False, a value of 0 will be supplied if the object
00100         hasn't already been seen.  Otherwise, a new (and previously unused)
00101         value will be allocated to the object.
00102 
00103         The mutex should be held when this is called.
00104 
00105         """
00106         try:
00107             num = self._objs[obj]
00108             return num.obj
00109         except KeyError:
00110             pass
00111 
00112         if not maybe_new:
00113             return 0
00114 
00115         self._objs[obj] = NotifyingDeleteObject(self._next_num, self._obj_gone)
00116         self._next_num += 1
00117         return self._next_num - 1

Here is the call graph for this function:

Here is the caller graph for this function:

def MoinMoin.support.xappy.replaylog.ReplayLog._get_xap_name (   self,
  obj,
  maybe_new = False 
) [private]
Get the name of a xapian class or method.

The mutex should be held when this is called.

Definition at line 138 of file replaylog.py.

00138 
00139     def _get_xap_name(self, obj, maybe_new=False):
00140         """Get the name of a xapian class or method.
00141 
00142         The mutex should be held when this is called.
00143 
00144         """
00145         # Check if it's a xapian class, or subclass.
00146         if isinstance(obj, types.TypeType):
00147             classname = self._xapian_classes.get(obj, None)
00148             if classname is not None:
00149                 return classname
00150 
00151             for classobj, classname in self._xapian_classes.iteritems():
00152                 if issubclass(obj, classobj):
00153                     return "subclassof_%s" % (classname, )
00154 
00155             return None
00156 
00157         # Check if it's a xapian function.
00158         if isinstance(obj, types.BuiltinFunctionType):
00159             funcname = self._xapian_functions.get(obj, None)
00160             if funcname is not None:
00161                 return funcname
00162 
00163         # Check if it's a proxied object.
00164         if isinstance(obj, LoggedProxy):
00165             classname = self._xapian_classes.get(obj.__class__, None)
00166             if classname is not None:
00167                 objnum = self._get_obj_num(obj, maybe_new=maybe_new)
00168                 return "%s#%d" % (classname, objnum)
00169 
00170         # Check if it's a proxied method.
00171         if isinstance(obj, LoggedProxyMethod):
00172             classname, methodname = self._xapian_methods[obj.real.im_func]
00173             objnum = self._get_obj_num(obj.proxyobj, maybe_new=maybe_new)
00174             return "%s#%d.%s" % (classname, objnum, methodname)
00175 
00176         # Check if it's a subclass of a xapian class.  Note: this will only
00177         # pick up subclasses, because the original classes are filtered out
00178         # higher up.
00179         for classobj, classname in self._xapian_classes.iteritems():
00180             if isinstance(obj, classobj):
00181                 objnum = self._get_obj_num(obj, maybe_new=maybe_new)
00182                 return "subclassof_%s#%d" % (classname, objnum)
00183 
00184         return None

Here is the call graph for this function:

Here is the caller graph for this function:

def MoinMoin.support.xappy.replaylog.ReplayLog._is_xap_obj (   self,
  obj 
) [private]
Return True iff an object is an instance of a xapian object.

(Also returns true if the object is an instance of a subclass of a
xapian object.)

The mutex should be held when this is called.

Definition at line 118 of file replaylog.py.

00118 
00119     def _is_xap_obj(self, obj):
00120         """Return True iff an object is an instance of a xapian object.
00121 
00122         (Also returns true if the object is an instance of a subclass of a
00123         xapian object.)
00124 
00125         The mutex should be held when this is called.
00126 
00127         """
00128         # Check for xapian classes.
00129         classname = self._xapian_classes.get(type(obj), None)
00130         if classname is not None:
00131             return True
00132         # Check for subclasses of xapian classes.
00133         for classobj, classname in self._xapian_classes.iteritems():
00134             if isinstance(obj, classobj):
00135                 return True
00136         # Not a xapian class or subclass.
00137         return False

Here is the caller graph for this function:

def MoinMoin.support.xappy.replaylog.ReplayLog._log (   self,
  msg 
) [private]

Definition at line 185 of file replaylog.py.

00185 
00186     def _log(self, msg):
00187         self._fd_mutex.acquire()
00188         try:
00189 #            msg = '%s,%s' % (
00190 #                datetime.datetime.fromtimestamp(time.time()).isoformat(),
00191 #                msg,
00192 #            )
00193             self._fd.write(msg)
00194             self._fd.flush()
00195         finally:
00196             self._fd_mutex.release()

Here is the caller graph for this function:

def MoinMoin.support.xappy.replaylog.ReplayLog._obj_gone (   self,
  num 
) [private]
Log that an object has been deleted.

Definition at line 322 of file replaylog.py.

00322 
00323     def _obj_gone(self, num):
00324         """Log that an object has been deleted.
00325 
00326         """
00327         self._log('DEL:#%d\n' % num)

Here is the call graph for this function:

Here is the caller graph for this function:

def MoinMoin.support.xappy.replaylog.ReplayLog._repr_arg (   self,
  arg 
) [private]
Return a representation of an argument.

The mutex should be held when this is called.

Definition at line 197 of file replaylog.py.

00197 
00198     def _repr_arg(self, arg):
00199         """Return a representation of an argument.
00200 
00201         The mutex should be held when this is called.
00202 
00203         """
00204 
00205         xapargname = self._get_xap_name(arg)
00206         if xapargname is not None:
00207             return xapargname
00208 
00209         if isinstance(arg, basestring):
00210             if isinstance(arg, unicode):
00211                 arg = arg.encode('utf-8')
00212             return 'str(%d,%s)' % (len(arg), arg)
00213 
00214         if isinstance(arg, long):
00215             try:
00216                 arg = int(arg)
00217             except OverFlowError:
00218                 pass
00219 
00220         if isinstance(arg, long):
00221             return 'long(%d)' % arg
00222 
00223         if isinstance(arg, int):
00224             return 'int(%d)' % arg
00225 
00226         if isinstance(arg, float):
00227             return 'float(%f)' % arg
00228 
00229         if arg is None:
00230             return 'None'
00231 
00232         if hasattr(arg, '__iter__'):
00233             seq = []
00234             for item in arg:
00235                 seq.append(self._repr_arg(item))
00236             return 'list(%s)' % ','.join(seq)
00237 
00238         return 'UNKNOWN:' + str(arg)

Here is the call graph for this function:

Here is the caller graph for this function:

def MoinMoin.support.xappy.replaylog.ReplayLog._repr_args (   self,
  args 
) [private]
Return a representation of a list of arguments.

The mutex should be held when this is called.

Definition at line 239 of file replaylog.py.

00239 
00240     def _repr_args(self, args):
00241         """Return a representation of a list of arguments.
00242 
00243         The mutex should be held when this is called.
00244 
00245         """
00246         logargs = []
00247         for arg in args:
00248             logargs.append(self._repr_arg(arg))
00249         return ','.join(logargs)

Here is the call graph for this function:

Here is the caller graph for this function:

def MoinMoin.support.xappy.replaylog.ReplayLog.log_call (   self,
  call,
  args 
)
Add a log message about a call.

Returns a number for the call, so it can be tied to a particular
result.

Definition at line 271 of file replaylog.py.

00271 
00272     def log_call(self, call, *args):
00273         """Add a log message about a call.
00274 
00275         Returns a number for the call, so it can be tied to a particular
00276         result.
00277 
00278         """
00279         self._mutex.acquire()
00280         try:
00281             logargs = self._repr_args(args)
00282             xapobjname = self._get_xap_name(call)
00283             call_id = self._get_call_id()
00284         finally:
00285             self._mutex.release()
00286 
00287         if xapobjname is not None:
00288             self._log("CALL%s:%s(%s)\n" % (call_id, xapobjname, logargs))
00289         else:
00290             self._log("CALL%s:UNKNOWN:%r(%s)\n" % (call_id, call, logargs))
00291         return call_id

Here is the call graph for this function:

def MoinMoin.support.xappy.replaylog.ReplayLog.log_except (   self,
  etype,
  value,
  tb,
  call_id 
)
Log an exception which has occurred.

Definition at line 292 of file replaylog.py.

00292 
00293     def log_except(self, (etype, value, tb), call_id):
00294         """Log an exception which has occurred.
00295 
00296         """
00297         # No access to an members, so no need to acquire mutex.
00298         exc = traceback.format_exception_only(etype, value)
00299         self._log("EXCEPT%s:%s\n" % (call_id, ''.join(exc).strip()))

Here is the call graph for this function:

def MoinMoin.support.xappy.replaylog.ReplayLog.log_retval (   self,
  ret,
  call_id 
)
Log a return value.

Definition at line 300 of file replaylog.py.

00300 
00301     def log_retval(self, ret, call_id):
00302         """Log a return value.
00303 
00304         """
00305         if ret is None:
00306             self._log("RET%s:None\n" % call_id)
00307             return
00308 
00309         self._mutex.acquire()
00310         try:
00311             # If it's a xapian object, return a proxy for it.
00312             if self._is_xap_obj(ret):
00313                 ret = LoggedProxy(ret)
00314                 xapobjname = self._get_xap_name(ret, maybe_new=True)
00315             msg = "RET%s:%s\n" % (call_id, self._repr_arg(ret))
00316         finally:
00317             self._mutex.release()
00318 
00319         # Not a xapian object - just return it.
00320         self._log(msg)
00321         return ret

Here is the call graph for this function:


Member Data Documentation

Definition at line 67 of file replaylog.py.

Definition at line 66 of file replaylog.py.

Definition at line 70 of file replaylog.py.

Definition at line 71 of file replaylog.py.

Definition at line 77 of file replaylog.py.

Definition at line 73 of file replaylog.py.

Definition at line 76 of file replaylog.py.

Definition at line 74 of file replaylog.py.

Definition at line 79 of file replaylog.py.

Definition at line 80 of file replaylog.py.

Definition at line 81 of file replaylog.py.


The documentation for this class was generated from the following file: