def result(self, process_id): """ Get the result of the given process. If the process has not completed, returns None. Once the result has been successfully fetched, it cannot be fetched again. """ completed = False try: try: process = self._get_process(process_id) completed = process['completed'] except ThreadDiedBeforeCompletionError: completed = True raise finally: if completed is True: del getProcessRegistry(self.context)[process_id] if completed: response = self.request.response response_details = process.get('result') status, headers, cookies, body = response_details response.setStatus(status) # Overwriting headers/cookies here is a bit crude, I have # tried to use declared interface methods wherever possible # but there are some omissions that have to be worked # around. # Currently, ZPublisher.HTTPResponse doesn't implement # IHTTPResponse, even though HTTPRequest implements # IHTTPRequest. current_headers = getattr(response, 'headers', getattr(response, '_headers', {})) result_headers = dict([(k.lower(), v) for k, v in headers.items()]) for h in set(current_headers.keys() + result_headers.keys()): if h not in headers and h in current_headers: # no interface-friendly way to unset headers anyway. del current_headers[h] else: response.setHeader(h, result_headers[h]) # no interface-friendly way to enumerate response cookies # or unset cookies. attr = (hasattr(response, 'cookies') and 'cookies') or \ (hasattr(response, '_cookies') and '_cookies') setattr(response, attr, cookies) if IHTTPResponse.providedBy(response): response.setResult(body) else: response.setBody(body) return response else: return None
def process_wrapper(pid, request_body, request_environ): # Sets up everything we need to run a view method in a new Zope-ish # context, then runs it and stores the result for later retrieval. _process = None def my_mapply(object, positional=(), keyword={}, debug=None, maybe=None, missing_name=None, handle_class=None, context=None, bind=0): if not isinstance(keyword, Mapping): keyword = {} keyword['process_id'] = pid args = (getattr(object, '__run__', object),) kwargs = dict(positional=positional, keyword=keyword, debug=debug, maybe=maybe, context=context, bind=bind ) if missing_name is not None: kwargs['missing_name'] = missing_name if handle_class is not None: kwargs['handle_class'] = handle_class return mapply(*args, **kwargs) response = HTTPResponse(stdout=StringIO(), stderr=StringIO()) request = HTTPRequest(StringIO(request_body), request_environ, response) request.set('process_id', pid) import Zope2 app = Zope2.bobo_application.__bobo_traverse__(request) reg = getProcessRegistry(app) _process = reg.get(pid) # Run try: try: response = publish(request, 'Zope2', [None], mapply=my_mapply) # We can't just pass the response back, as the data streams will not # be set up right. attr = (hasattr(response, 'cookies') and 'cookies') or \ (hasattr(response, '_cookies') and '_cookies') cookies = deepcopy(getattr(response, attr)) if IHTTPResponse.providedBy(response): _process['result'] = (response.getStatus(), dict(response.getHeaders()), cookies, response.consumeBody()) else: # Currently, ZPublisher.HTTPResponse doesn't implement # IHTTPResponse, even though HTTPRequest implements # IHTTPRequest. _process['result'] = (response.getStatus(), dict(response.headers), cookies, response.body) except Exception, e: # Set result to the exception raised _process['result'] = e raise else:
def process_wrapper(pid, request_body, request_environ): # Sets up everything we need to run a view method in a new Zope-ish # context, then runs it and stores the result for later retrieval. _process = None def my_mapply(object, positional=(), keyword={}, debug=None, maybe=None, missing_name=None, handle_class=None, context=None, bind=0): if not isinstance(keyword, Mapping): keyword = {} keyword['process_id'] = pid args = (getattr(object, '__run__', object), ) kwargs = dict(positional=positional, keyword=keyword, debug=debug, maybe=maybe, context=context, bind=bind) if missing_name is not None: kwargs['missing_name'] = missing_name if handle_class is not None: kwargs['handle_class'] = handle_class return mapply(*args, **kwargs) response = HTTPResponse(stdout=StringIO(), stderr=StringIO()) request = HTTPRequest(StringIO(request_body), request_environ, response) request.set('process_id', pid) import Zope2 app = Zope2.bobo_application.__bobo_traverse__(request) reg = getProcessRegistry(app) _process = reg.get(pid) # Run try: try: response = publish(request, 'Zope2', [None], mapply=my_mapply) # We can't just pass the response back, as the data streams will not # be set up right. attr = (hasattr(response, 'cookies') and 'cookies') or \ (hasattr(response, '_cookies') and '_cookies') cookies = deepcopy(getattr(response, attr)) if IHTTPResponse.providedBy(response): _process['result'] = (response.getStatus(), dict(response.getHeaders()), cookies, response.consumeBody()) else: # Currently, ZPublisher.HTTPResponse doesn't implement # IHTTPResponse, even though HTTPRequest implements # IHTTPRequest. _process['result'] = (response.getStatus(), dict(response.headers), cookies, response.body) except Exception, e: # Set result to the exception raised _process['result'] = e raise else: