2014-12-10 4 views
0

Требование: UDP-сервер, который принимает UDP-пакет и сохраняет полученный пакет в одну из двух очередей. Рабочий поток связан с каждой очередью, а связанный поток собирает пакет с передней части очереди, обрабатывает его и записывает в систему кэша в памяти.libuv объединяет mutliple асинхронные вызовы и вызывает обратный вызов один раз

Ограничение: решение должно быть основано на событие петли (libuv) и написано на C

моего решения

  • зарегистрировать обратный вызов для входящего UDP, который добавляет полученный пакет в одну из двух очередей и вызывает uv_async_send

  • два глобальных объекта uv_sync_t создаются по одному для каждой очереди и используются как параметр для uv_async_send. Например: если пакет добавлен в очередь-один, то uv_sync_t object-1 используется как параметр для uv_async_send. Аналогичным образом, если пакет добавляется в очередь-два, то uv_sync_t объектно-2 используется

  • два потока запускаются, каждый из которых имеет свою собственную петлю и ручку, связанную с обратным вызовом

    • В потоке один uv_sync_t объект-1 связан с функцией (скажем funcA). В резьбовых два uv_sync_t объект-2 связан с другой функцией (скажу funcB)
    • funcA и funcB читает «Single» пакет из соответствующей очереди и сохраняет его в в памяти кэше

Проблема Клиент отправляет большое количество пакетов, которые регистрируют большое количество событий на сервере. Теперь проблема в том, что libuv объединяет несколько вызовов в один и вызывает один обратный вызов (который удаляет SINGLE-узел из очереди). Это приводит к ситуации, когда узлы добавляются в очередь с более высокой скоростью и удаляются с очень низкой скоростью. Могут ли эти ставки быть сбалансированными?

Есть ли лучший способ спроектировать сервер, используя библиотеку событий libru?

ответ

1

Поскольку вы размещаете пакеты в одном потоке, но обрабатываете их в другом, возможно, что они работают с немного разными ставками. Я бы использовал потокобезопасную очередь (посмотрите на concurrencykit.org) и обработал всю очередь на обратном вызове async вместо простой обработки одного пакета.