def send(self, item): """sends the given item to the other side of the channel, possibly blocking if the sender queue is full. Note that an item needs to be marshallable. """ if self.isclosed(): raise IOError, "cannot send to %r" % (self, ) if isinstance(item, Channel): data = Message.CHANNEL_NEW(self.id, item.id) else: data = Message.CHANNEL_DATA(self.id, item) self.gateway._send(data)
def _thread_receiver(self): """ thread to read and handle Messages half-sync-half-async. """ try: from sys import exc_info while 1: try: msg = Message.readfrom(self._io) self._trace("received <- %r" % msg) msg.received(self) except sysex: break except EOFError: break except: self._traceex(exc_info()) break finally: # XXX we need to signal fatal error states to # channels/callbacks, particularly ones # where the other side just died. self._stopexec() try: self._stopsend() except IOError: self._trace('IOError on _stopsend()') self._channelfactory._finished_receiving() self._trace('leaving %r' % threading.currentThread())
def _thread_receiver(self): """ thread to read and handle Messages half-sync-half-async. """ try: from sys import exc_info while 1: try: msg = Message.readfrom(self._io) self._trace("received <- %r" % msg) msg.received(self) except sysex: break except EOFError: break except: self._traceex(exc_info()) break finally: # XXX we need to signal fatal error states to # channels/callbacks, particularly ones # where the other side just died. self._stopexec() try: self._stopsend() except IOError: self._trace('IOError on _stopsend()') self._channelfactory._finished_receiving() if threading: # might be None during shutdown/finalization self._trace('leaving %r' % threading.currentThread())
def close(self, error=None): """ close down this channel on both sides. """ if not self._closed: # state transition "opened/sendonly" --> "closed" # threads warning: the channel might be closed under our feet, # but it's never damaging to send too many CHANNEL_CLOSE messages put = self.gateway._send if error is not None: put(Message.CHANNEL_CLOSE_ERROR(self.id, str(error))) else: put(Message.CHANNEL_CLOSE(self.id)) if isinstance(error, RemoteError): self._remoteerrors.append(error) self._closed = True # --> "closed" self._receiveclosed.set() queue = self._items if queue is not None: queue.put(ENDMARKER) self.gateway._channelfactory._no_longer_opened(self.id)
def _thread_receiver(self): """ thread to read and handle Messages half-sync-half-async. """ try: from sys import exc_info while 1: try: msg = Message.readfrom(self._io) self._trace("received <- %r" % msg) msg.received(self) except sysex: break except EOFError: break except: self._traceex(exc_info()) break finally: self._send(None) self._channelfactory._finished_receiving() self._trace('leaving %r' % threading.currentThread())
def remote_exec(self, source, stdout=None, stderr=None): """ return channel object and connect it to a remote execution thread where the given 'source' executes and has the sister 'channel' object in its global namespace. The callback functions 'stdout' and 'stderr' get called on receival of remote stdout/stderr output strings. """ try: source = str(Source(source)) except NameError: try: import py source = str(py.code.Source(source)) except ImportError: pass channel = self.newchannel() outid = self._newredirectchannelid(stdout) errid = self._newredirectchannelid(stderr) self._send(Message.CHANNEL_OPEN( channel.id, (source, outid, errid))) return channel