class Sandbox(object): def __init__(self): self._events = dict() self._logger = Logger() def invoke(self, event_name, request, stream): """ Connect worker and decorator """ event_closure = self._events.get(event_name, None) if event_closure is not None: event_handler = event_closure() event_handler.invoke(request, stream) else: self._logger.warn("There is no handler for event %s" % event_name) def on(self, event_name, event_handler): try: # Try to construct handler. closure = event_handler() except Exception: # If this callable object is not our wrapper - may raise Exception closure = default(event_handler)() if hasattr(closure, "_wrapped"): event_handler = default(event_handler) else: if not hasattr(closure, "_wrapped"): event_handler = default(event_handler) self._events[event_name] = event_handler
class Request(object): def __init__(self): self._logger = Logger() self.cache = list() self._clbk = None # Callback - on chunk self._errbk = None # Errorback - translate error to handler self._errmsg = None # Store message self._state = 1 # Status of stream (close/open) def push(self, chunk): if self._clbk is None: # If there is no attachment object, put chunk in the cache self._logger.debug("Cache chunk") self.cache.append(chunk) else: # Copy callback to temp, clear current callback and perform temp # Do it so because self._clbk may change, while perfoming callback function. # Avoid double chunk sending to the task self._logger.debug("Send chunk to application") temp = self._clbk self._clbk = None temp(chunk) def error(self, errormsg): self._errmsg = errormsg def close(self): self._logger.debug("Close request") self._state = None if len(self.cache) == 0 and self._clbk is not None: self._logger.warn("Chunks are over, but the application requests them") if self._errbk is not None: self._logger.error("Throw error") self._errbk(RequestError("No chunks are available")) else: self._logger.error("No errorback. Can't throw error") def read(self): def wrapper(clbk, errorback=None): self._read(clbk, errorback) return wrapper def _read(self, callback, errorback): if len(self.cache) > 0: callback(self.cache.pop(0)) elif self._errmsg is not None: errorback(self._errmsg) #traslate error into worker elif self._state is not None: self._clbk = callback self._errbk = errorback else: #Stream closed by choke #Raise exception here because no chunks from cocaine-runtime are availaible self._logger.warn("Chunks are over, but the application requests them") errorback(RequestError("No chunks are available"))