def test_servlet(): req_mock = RequestMock() resp_mock = ResponseMock() bridge = RequestBridge(req_mock, AdaptedInputStream(), AdaptedErrLog()) bridge_map = dict_builder(bridge.asMap)() req_wrapper = bridge.asWrapper() servlet = WSGIServlet() servlet.init( ServletConfigMock({"wsgi.handler": "servlet_support.simple_app"})) servlet.service(req_wrapper, resp_mock) assert next(resp_mock.outputStream) == b"Hello world!\n" assert resp_mock.getHeader('Content-Type') == 'text/plain' assert resp_mock.getStatus() == 200
def test_servlet(): req_mock = RequestMock() resp_mock = ResponseMock() bridge = RequestBridge(req_mock, AdaptedInputStream(), AdaptedErrLog()) bridge_map = dict_builder(bridge.asMap)() req_wrapper = bridge.asWrapper() servlet = WSGIServlet() servlet.init(ServletConfigMock( { "wsgi.handler": "servlet_support.simple_app" })) servlet.service(req_wrapper, resp_mock) assert next(resp_mock.outputStream) == b"Hello world!\n" assert resp_mock.getHeader('Content-Type') == 'text/plain' assert resp_mock.getStatus() == 200
def filter_wsgi_call(self, req, resp, chain): bridge = RequestBridge(req, self.err_log, AdaptedInputStream(req.getInputStream())) environ = dict_builder(bridge.asMap)() # Can only set up the actual wrapped response once the filter coroutine is set up wrapped_req = bridge.asWrapper() call = WSGICall(environ, req, resp) progress = [ ] # FIXME currently we are using three states - [], [False], [True] - which is pretty awful # FIXME instead something like [PROBING], [INCREMENTAL], [BATCH] probably would work better call_filter = None def setup_coupler(): (yield) # @validator def null_app(environ, start_response): # print "null_app environ=%s start_response=%s" % (environ, start_response) #for name in call.wrapped_resp.getHeaders(): # ... response_headers = [] for name in call.wrapped_resp.getHeaderNames(): for value in call.wrapped_resp.getHeaders(name): response_headers.append( (str(name), value.encode("latin1"))) # Is it possible to get the underlying status from the response? status = "%s FIXME" % (call.wrapped_resp.getStatus(), ) # Reset the underlying response so we can re-write headers/status; # otherwise we will get duplicated headers call.wrapped_resp.reset() start_response(status, response_headers) output_stream = call.wrapped_resp.getOutputStream() for i, chunk in enumerate(output_stream): # print >> sys.stderr, "Got this chunk %d %r (%r)" % (i, chunk, progress) # check if stalled (is there no progress in the below while loop?) # if stalled, we have to wait until the filter chain is complete before # we can return another chunk yield chunk if not progress: progress[:] = [False] # need three states! FIXME def f(s): pass # print "null_app stalled value %r" % (s,) output_stream.callback = f call_filter() # print >> sys.stderr, "Filter chain completed" for chunk in output_stream.getChunks(): yield chunk return if i > 100: raise AssertionError( "Stopping, obviously we are broken!!!!!") wsgi_filter = self.application(null_app) result = wsgi_filter(call.environ, call.start_response) # print >> sys.stderr, "got result from wsgi_filter %s" % (result,) it = iter(result) while True: try: # print >> sys.stderr, "waiting on yield" if not progress or progress[0] != False: data = (yield) else: data = None # print >> sys.stderr, "completed yield, waiting on next of %s" % (it,) filtered = next(it) progress[:] = [True] # print >> sys.stderr, "%r -> %r" % (data, filtered) # print >> sys.stderr, "call %r" % (call,) call.write(filtered) except StopIteration: break if not call.headers_sent: call.write("") # send headers now if body was empty coupler = setup_coupler() # fill in the wrapping servlet response call.wrapped_resp = CaptureHttpServletResponse(resp, coupler.send) call_filter = lambda: chain.doFilter( wrapped_req, call.wrapped_resp ) # FIXME maybe name "complete_filter_chain"? coupler.send(None) # advance the coroutine to before filtering coupler.send( None) # advance one more time to after sending the response if not progress or progress[0] != False: # print >> sys.stderr, "Calling filter" call_filter() else: pass # print >> sys.stderr, "Not calling filter, should be done in null_app" # print >> sys.stderr, "Closing coupler" coupler.close() # put in a try-finally context
# changing daemonization only makes sense in Java when the # thread is alive; need extra test on the exception # because of possible races on interrogating with getState raise RuntimeError("cannot set daemon status of active thread") daemon = property(isDaemon, setDaemon) def __tojava__(self, c): if isinstance(self._thread, c): return self._thread if isinstance(self, c): return self return Py.NoConversion _threads = dict_builder(MapMaker().weakValues().makeMap)() _active = _threads def _register_thread(jthread, pythread): _threads[jthread.getId()] = pythread def _unregister_thread(jthread): _threads.pop(jthread.getId(), None) class Thread(JavaThread): def __init__(self, group=None, target=None, name=None, args=None, kwargs=None): assert group is None, "group argument must be None for now" _thread = self._create_thread() JavaThread.__init__(self, _thread)
def service(self, req, resp): bridge = self.get_bridge(req) environ = dict_builder(bridge.asMap)() self.do_wsgi_call(WSGICall(environ, req, resp))
# changing daemonization only makes sense in Java when the # thread is alive; need extra test on the exception # because of possible races on interrogating with getState raise RuntimeError("cannot set daemon status of active thread") daemon = property(isDaemon, setDaemon) def __tojava__(self, c): if isinstance(self._thread, c): return self._thread if isinstance(self, c): return self return Py.NoConversion _threads = dict_builder(MapMaker().weakValues().makeMap)() _active = _threads def _register_thread(jthread, pythread): _threads[jthread.getId()] = pythread def _unregister_thread(jthread): _threads.pop(jthread.getId(), None) class Thread(JavaThread): def __init__(self, group=None, target=None,
for value in self.itervalues(): yield ref(value) def valuerefs(self): """Return a list of weak references to the values. The references are not guaranteed to be 'live' at the time they are used, so the result of calling the references needs to be checked before being used. This can be used to avoid creating references that will cause the garbage collector to keep the values around longer than needed. """ return [ref(value) for value in self.itervalues()] WeakValueDictionaryBuilder = dict_builder(MapMaker().weakValues().makeMap, WeakValueDictionary) class WeakKeyDictionary(dict): """ Mapping class that references keys weakly. Entries in the dictionary will be discarded when there is no longer a strong reference to the key. This can be used to associate additional data with an object owned by other parts of an application without adding attributes to those objects. This can be especially useful with objects that override attribute accesses. """ def __new__(cls, *args, **kw): return WeakKeyDictionaryBuilder(*args, **kw)
def filter_wsgi_call(self, req, resp, chain): bridge = RequestBridge(req, self.err_log, AdaptedInputStream(req.getInputStream())) environ = dict_builder(bridge.asMap)() # Can only set up the actual wrapped response once the filter coroutine is set up wrapped_req = bridge.asWrapper() call = WSGICall(environ, req, resp) progress = [] # FIXME currently we are using three states - [], [False], [True] - which is pretty awful # FIXME instead something like [PROBING], [INCREMENTAL], [BATCH] probably would work better call_filter = None def setup_coupler(): (yield) # @validator def null_app(environ, start_response): # print "null_app environ=%s start_response=%s" % (environ, start_response) #for name in call.wrapped_resp.getHeaders(): # ... response_headers = [] for name in call.wrapped_resp.getHeaderNames(): for value in call.wrapped_resp.getHeaders(name): response_headers.append((str(name), value.encode("latin1"))) # Is it possible to get the underlying status from the response? status = "%s FIXME" % (call.wrapped_resp.getStatus(),) # Reset the underlying response so we can re-write headers/status; # otherwise we will get duplicated headers call.wrapped_resp.reset() start_response(status, response_headers) output_stream = call.wrapped_resp.getOutputStream() for i, chunk in enumerate(output_stream): # print >> sys.stderr, "Got this chunk %d %r (%r)" % (i, chunk, progress) # check if stalled (is there no progress in the below while loop?) # if stalled, we have to wait until the filter chain is complete before # we can return another chunk yield chunk if not progress: progress[:] = [False] # need three states! FIXME def f(s): pass # print "null_app stalled value %r" % (s,) output_stream.callback = f call_filter() # print >> sys.stderr, "Filter chain completed" for chunk in output_stream.getChunks(): yield chunk return if i > 100: raise AssertionError("Stopping, obviously we are broken!!!!!") wsgi_filter = self.application(null_app) result = wsgi_filter(call.environ, call.start_response) # print >> sys.stderr, "got result from wsgi_filter %s" % (result,) it = iter(result) while True: try: # print >> sys.stderr, "waiting on yield" if not progress or progress[0] != False: data = (yield) else: data = None # print >> sys.stderr, "completed yield, waiting on next of %s" % (it,) filtered = next(it) progress[:] = [True] # print >> sys.stderr, "%r -> %r" % (data, filtered) # print >> sys.stderr, "call %r" % (call,) call.write(filtered) except StopIteration: break if not call.headers_sent: call.write("") # send headers now if body was empty coupler = setup_coupler() # fill in the wrapping servlet response call.wrapped_resp = CaptureHttpServletResponse(resp, coupler.send) call_filter = lambda: chain.doFilter(wrapped_req, call.wrapped_resp) # FIXME maybe name "complete_filter_chain"? coupler.send(None) # advance the coroutine to before filtering coupler.send(None) # advance one more time to after sending the response if not progress or progress[0] != False: # print >> sys.stderr, "Calling filter" call_filter() else: pass # print >> sys.stderr, "Not calling filter, should be done in null_app" # print >> sys.stderr, "Closing coupler" coupler.close() # put in a try-finally context
yield ref(value) def valuerefs(self): """Return a list of weak references to the values. The references are not guaranteed to be 'live' at the time they are used, so the result of calling the references needs to be checked before being used. This can be used to avoid creating references that will cause the garbage collector to keep the values around longer than needed. """ return [ref(value) for value in list(self.values())] WeakValueDictionaryBuilder = dict_builder(MapMaker().weakValues().makeMap, WeakValueDictionary) class WeakKeyDictionary(dict): """ Mapping class that references keys weakly. Entries in the dictionary will be discarded when there is no longer a strong reference to the key. This can be used to associate additional data with an object owned by other parts of an application without adding attributes to those objects. This can be especially useful with objects that override attribute accesses. """ def __new__(cls, *args, **kw): return WeakKeyDictionaryBuilder(*args, **kw)