Как читать из (hdf5) файла в асинхронных контекстах? - PullRequest
0 голосов
/ 30 ноября 2018

В последнее время я немного поигрался с асинхронными функциями Python 3.В целом, я доволен синтаксисом 3.6 и, конечно, повышением производительности, которое вы получаете.Один из захватывающих проектов, которые развиваются вокруг стандарта ASGI, на мой взгляд, - starlette .У меня запущен пример приложения, в котором я читаю данные из файла hdf5.h5py пока не поддерживает асинхронный ввод-вывод.В связи с этим возникает вопрос: имеет ли смысл то, что я здесь делаю?Насколько я понимаю, этот код работает синхронно в конце концов.Каков рекомендуемый способ ввода / вывода в асинхронных контекстах?

async def _flow(indexes):
    print('received flow indexes %s ' %indexes)
    # uses h5py under the hood
    gr = GridH5ResultAdmin(gridadmin_f, results_f)
    t = gr.nodes.timeseries(indexes=indexes)
    data = t.only('s1').data
    # data is a numpy array
    return data['s1'].tolist()

@app.route('/flow_velocity')
async def flow_results(request):

    indexes_list = [[2,3,4,5], [6,7,8,9], [10,11,12,13]]

    tasks = []
    loop = asyncio.get_event_loop()
    t0 = datetime.datetime.now()
    for indexes in indexes_list:
        print('Start getting indexes %s' % indexes)
        # Launch a coroutine for each data fetch
        task = loop.create_task(_flow(indexes))
        tasks.append(task)

    # Wait on, and then gather, all data
    flow_data = await asyncio.gather(*tasks)
    dt = (datetime.datetime.now() - t0).total_seconds()
    print('elapsed time: {} [s]'.format(dt))

    return JSONResponse({'flow_velocity': flow_data})

Регистрация:

INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
Start getting indexes "[2, 3, 4, 5]"
Start getting indexes "[6, 7, 8, 9]"
Start getting indexes "[10, 11, 12, 13]"
received flow indexes [2, 3, 4, 5] 
received flow indexes [6, 7, 8, 9] 
received flow indexes [10, 11, 12, 13]
elapsed time: 1.49779 [s]

1 Ответ

0 голосов
/ 01 августа 2019

К сожалению, с модулем h5py вы не можете использовать asyncio, то, что вы здесь делаете, в основном последовательное, потому что если часть ввода / вывода не может быть выполнена асинхронно, то остальная часть вашего асинхронного кодане имеет большого значения осталось

https://github.com/h5py/h5py/issues/837

Сводка из этой темы

Таким образом, есть две отдельные проблемы с добавлением asyncioподдержка:

  1. asyncio явно не поддерживает ввод / вывод файловой системы в данный момент, см., например, https://github.com/python/asyncio/wiki/ThirdParty#filesystem, https://groups.google.com/forum/#!topic/python-tulip/MvpkQeetWZA, Каков статус асинхронного ввода-вывода POSIXO (AIO)? и https://github.com/Tinche/aiofiles, что наиболее близко к желанию.
  2. Все операции ввода-вывода выполняются через HDF5 (библиотека), поэтому независимо от поддержки асинхронностивы хотите добавить, что вам нужна поддержка в HDF5 (библиотека)

Это означает, что h5py вряд ли когда-либо будет поддерживать asyncio.

Вы можете попробовать запустить что-то в потоке, нет никаких гарантий, что он будет работать хорошо, хотя, как я упоминал, HDF5 контролирует ввод-вывод, и вы захотите убедиться, что вы не столкнетесь ни с одним из егоблокировка управления.Вы, вероятно, захотите понять, какой режим файлов, упомянутый в http://docs.h5py.org/en/latest/high/file.html#file-drivers, подойдет вам лучше всего.Может быть, вы могли бы рассмотреть другие альтернативы, такие как многопроцессорность или concurrent.futures?

...