Tornado PipeIOStream: OSError: [Errno 9] Неверный дескриптор файла - PullRequest
0 голосов
/ 31 мая 2018

У меня есть небольшой микро-сервис, который хранит сообщения, локально идентифицированные по идентификаторам.Чтобы гарантировать, что файлы не будут записываться одновременно, я реализовал очередь.Следующий код работает только один раз, вторая загрузка файла приводит к обратной трассировке ниже, я действительно не знаю, как правильно обрабатывать fd.

from tornado import web, ioloop, gen
from tornado.queues import Queue
from tornado.iostream import PipeIOStream

class Sample:
    def __init__(self):
        self.queue = Queue()

    @gen.coroutine
    def write_queue(self):
        while True:
            item = yield self.queue.get()
            print("Message with id %s stored" % item[0])
            fd = open(item[0], 'ab')
            stream = PipeIOStream(fd.fileno())
            yield stream.write(item[1])
            stream.close_fd()

class MainHandler(web.RequestHandler):

    def initialize(self, store):
        self.store = store

    @gen.coroutine
    def put(self, id):
        yield self.store.queue.put((id, self.request.body))


def start(store):
    return web.Application([
        (r"/(.*)", MainHandler,
         {"store": store})
    ])

if __name__ == '__main__':
    store = Store()
    app = start(store)
    app.listen(8888)
    ioloop.IOLoop.current().add_callback(store.write_queue)
    ioloop.IOLoop.current().start()




ERROR:tornado.application:Exception in callback functools.partial(<function wrap.<locals>.null_wrapper at 0x7f46657f46a8>, <Future finished exception=OSError(9, 'Bad file descriptor')>)
Traceback (most recent call last):

    stream = PipeIOStream(fd.fileno())
  File "/usr/local/lib/python3.5/dist-packages/tornado/iostream.py", line 1643, in __init__
    self._fio = io.FileIO(self.fd, "r+")
OSError: [Errno 9] Bad file descriptor

1 Ответ

0 голосов
/ 01 июня 2018
  1. Дескриптор файла, возвращаемый open, не является каналом.Обычно разрешено использовать обычные файлы с PipeIOStream, но это не полезно в Linux.Такие файловые дескрипторы всегда считываются читаемыми, и чтение из них или запись в них всегда блокируется.Поэтому использовать PipeIOStream, как это, не лучше, чем просто fd.write(item[1]).

  2. Вы открыли файл в режиме только для записи, но PipeIOStream оборачивает его в оболочку для чтения / записи (на самом деле я немного удивлен, что это когда-либо работает, так как реальнотрубы односторонние).Я думаю , откуда это исключение.Если вы открыли файл в режиме 'ab+', я думаю, что он будет работать.Я не пробовал это, хотя.

...