2011-07-15 19:06:02 +00:00
|
|
|
import bunch
|
|
|
|
import collections
|
|
|
|
import gevent
|
2011-07-15 21:19:58 +00:00
|
|
|
import sys
|
2011-07-15 19:06:02 +00:00
|
|
|
import time
|
|
|
|
import traceback
|
|
|
|
import yaml
|
|
|
|
|
|
|
|
from ..common import context
|
|
|
|
|
|
|
|
context.update(bunch.Bunch(
|
|
|
|
result_queue = collections.deque(),
|
|
|
|
))
|
|
|
|
|
|
|
|
|
|
|
|
class TransferGreenletResult(object):
|
|
|
|
""" Generic container object. Weeeeeeeeeeeeeee *short* """
|
|
|
|
def __init__(self, type):
|
2011-07-15 21:19:58 +00:00
|
|
|
# About the Greenlet
|
|
|
|
self.type = type
|
|
|
|
|
2011-07-15 19:06:02 +00:00
|
|
|
# About the key
|
2011-07-15 21:19:58 +00:00
|
|
|
self.bucket = None
|
|
|
|
self.key = None
|
2011-07-15 19:06:02 +00:00
|
|
|
self.size = None
|
|
|
|
|
|
|
|
# About the job
|
|
|
|
self.success = False
|
2011-07-15 21:19:58 +00:00
|
|
|
self.error = None
|
|
|
|
|
2011-07-15 19:06:02 +00:00
|
|
|
self.start_time = None
|
|
|
|
self.finish_time = None
|
|
|
|
|
|
|
|
self.duration = None
|
2011-07-15 21:19:58 +00:00
|
|
|
self.latency = None
|
|
|
|
|
|
|
|
self.request_start = None
|
|
|
|
self.request_finish = None
|
2011-07-15 19:06:02 +00:00
|
|
|
|
2011-07-15 21:19:58 +00:00
|
|
|
self.chunks = None
|
2011-07-15 19:06:02 +00:00
|
|
|
|
2011-07-15 21:19:58 +00:00
|
|
|
def markStarted(self):
|
|
|
|
self.start_time = time.time()
|
2011-07-15 19:06:02 +00:00
|
|
|
|
2011-07-15 21:19:58 +00:00
|
|
|
def markFinished(self):
|
|
|
|
self.finish_time = time.time()
|
|
|
|
self.duration = self.finish_time - self.start_time
|
2011-07-15 19:06:02 +00:00
|
|
|
context.result_queue.append(self)
|
|
|
|
|
2011-07-15 21:19:58 +00:00
|
|
|
def setKey(self, key):
|
|
|
|
self.key = key.name
|
|
|
|
self.bucket = key.bucket.name
|
|
|
|
|
|
|
|
def setError(self, message='Unhandled Exception', show_traceback=False):
|
|
|
|
""" Sets an error state in the result, and returns False... example usage:
|
|
|
|
|
|
|
|
return self.result.setError('Something happened', traceback=True)
|
|
|
|
"""
|
|
|
|
self.error = dict()
|
|
|
|
self.error['msg'] = message
|
|
|
|
if show_traceback:
|
|
|
|
self.error['traceback'] = traceback.format_exc()
|
|
|
|
return False
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def repr_yaml(c, dumper, self):
|
|
|
|
data = dict()
|
|
|
|
for x in ('type', 'bucket', 'key', 'chunks'):
|
|
|
|
data[x] = self.__dict__[x]
|
|
|
|
|
|
|
|
# reader => r, writer => w
|
|
|
|
data['type'] = data['type'][0]#chunks
|
|
|
|
|
|
|
|
# the error key must be present ONLY on failure.
|
|
|
|
assert not (self.success and self.error)
|
|
|
|
if self.success:
|
|
|
|
assert self.error == None
|
|
|
|
else:
|
|
|
|
assert self.error != None
|
|
|
|
data['error'] = self.error
|
|
|
|
|
|
|
|
data['start'] = self.request_start
|
|
|
|
if self.request_finish:
|
|
|
|
data['duration'] = 1000000000 * (self.request_finish - self.request_start)
|
|
|
|
|
|
|
|
return dumper.represent_dict(data)
|
2011-07-15 19:06:02 +00:00
|
|
|
|
|
|
|
# And a representer for dumping a TransferGreenletResult as a YAML dict()
|
2011-07-15 21:19:58 +00:00
|
|
|
yaml.add_representer(TransferGreenletResult, TransferGreenletResult.repr_yaml)
|
2011-07-15 19:06:02 +00:00
|
|
|
|
|
|
|
|
|
|
|
class ResultsLogger(gevent.Greenlet):
|
|
|
|
""" A quick little greenlet to always run and dump results. """
|
|
|
|
def __init__(self):
|
|
|
|
gevent.Greenlet.__init__(self)
|
2011-07-19 00:04:36 +00:00
|
|
|
self.outfile = context.real_stdout
|
2011-07-15 19:06:02 +00:00
|
|
|
|
|
|
|
def _run(self):
|
|
|
|
while True:
|
|
|
|
try:
|
|
|
|
self._doit()
|
|
|
|
except:
|
|
|
|
print "An exception was encountered while dumping the results... this shouldn't happen!"
|
|
|
|
traceback.print_exc()
|
|
|
|
time.sleep(0.1)
|
|
|
|
|
|
|
|
def _doit(self):
|
|
|
|
while context.result_queue:
|
|
|
|
result = context.result_queue.popleft()
|
|
|
|
yrep = yaml.dump(result)
|
2011-07-15 21:19:58 +00:00
|
|
|
self.outfile.write(yrep + "---\n")
|
2011-07-15 19:06:02 +00:00
|
|
|
|