Add support for reopening closed pipes with consistency guarantees
This commit is contained in:
		@@ -15,21 +15,29 @@ class PipeWriterThread(Thread):
 | 
			
		||||
        self._write_queue = Queue()
 | 
			
		||||
 | 
			
		||||
    def write(self, message):
 | 
			
		||||
        self._write_queue.put(message, block=True)
 | 
			
		||||
        self._write_queue.put(message, block=False)
 | 
			
		||||
 | 
			
		||||
    @terminate_process_on_failure
 | 
			
		||||
    def run(self):
 | 
			
		||||
        try:
 | 
			
		||||
            with open(self._pipe_path, 'wb') as pipe:
 | 
			
		||||
                while True:
 | 
			
		||||
                    message = self._write_queue.get(block=True)
 | 
			
		||||
                    if message is None:
 | 
			
		||||
                        self._stop_event.set()
 | 
			
		||||
                        break
 | 
			
		||||
        with self._open() as pipe:
 | 
			
		||||
            while True:
 | 
			
		||||
                message = self._write_queue.get(block=True)
 | 
			
		||||
                if message is None:
 | 
			
		||||
                    self._stop_event.set()
 | 
			
		||||
                    break
 | 
			
		||||
                try:
 | 
			
		||||
                    pipe.write(message + b'\n')
 | 
			
		||||
                    pipe.flush()
 | 
			
		||||
        except BrokenPipeError:
 | 
			
		||||
            self._stop_event.set()
 | 
			
		||||
                except BrokenPipeError:
 | 
			
		||||
                    try:  # pipe was reopened, close() flushed the message
 | 
			
		||||
                        pipe.close()
 | 
			
		||||
                    except BrokenPipeError:  # close() discarded the message
 | 
			
		||||
                        # TODO: a message is lost here, implement thread safe, blocking deque
 | 
			
		||||
                        pass
 | 
			
		||||
                    pipe = self._open()
 | 
			
		||||
 | 
			
		||||
    def _open(self):
 | 
			
		||||
        return open(self._pipe_path, 'wb')
 | 
			
		||||
 | 
			
		||||
    def stop(self):
 | 
			
		||||
        self.unblock()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user