К вопросу использования #epoll вместо хорошо знакомых и «традиционных» select & poll. Т.е. асинхронной работы с чем-либо посредством polling’а и мультиплексирования.
Недавно пришлось заниматься реализацией очереди событий для AMQP-CPP. В одном из продуктов решено сделать связь агентских частей с основным «контроллером» через #AMQP, в качестве брокера #RabbitMQ (всё стандартно, обычный кластер и TLS-соединения).
Вот только агенты продукта активно используют асинхронно-реактивное программирование с хорошей «горизонтальной масштабируемостью». Когда достигнуто полноценное sharing nothing, не просто горизонтальная масштабируемость через lock-free или wait-free и закон Амдала. Исключается много всего и сразу, как старый-добрый cache ping-pong, так и печаль с false sharing.
Отсюда внутри агентов и своё управление потоками с выделениями памяти. Не только в плане heap (динамической памяти, со своими аллокаторами а-ля #jemalloc от #Facebook), но и приколы вокруг узлов #NUMA и даже huge pages (снижающих «давление» на #TLB, меньше промахов).
Первая же проблема выплыла почти сразу — не реально использовать библиотеку AMQP-CPP с уже предоставляющейся поддержкой #libev, #libuv, #libevent. Несовместимы эти очереди сообщений с имеющейся моделью управления потоками и организации задач на агентах.
Почему был взят epollПодход используемый в #epoll выглядит более современно, меньше копирований памяти между user space и kernel space. А при появлении данных в отслеживаемом файловом дескрипторе можно напрямую перейти по указателю на объект класса или структуру данных. Тем самым обходиться без поиска дескриптора по индексным массивам/контейнерам. Сразу же работать с экземплярами объектов оборачивающих нужное #tcp -соединение, того самого, в которое и пришли данные.
И тут обозначилась вторая проблема, что используема AMQP-библиотека не вычитывает данные целиком из потока сокета. Например, забирает данные лишь до тех пор, пока не насытится автомат состояний (finite-state machine), выполняющий парсинг сущностей AMQP-протокола.
Используя #epoll приходится выбирать на какой вариант обработки событий ориентироваться:
И беда с библиотекой в очередной раз показала, что нельзя использовать работу «по фронту» (edge-triggered) не изучив досконально работу подсистемы отвечающей за вычитывание данных из файловых дескрипторов. И появление флага EPOLLET в коде является маркером, о том, чтобы проводить аудит использовавшихся решений.
Про Edge Triggered Vs Level Triggered interrupts можно почитать в https://venkateshabbarapu.blogspot.com/2013/03/edge-triggered-vs-level-triggered.html)
#tmux wykrzacza się z #libevent 2.2.1 (alpha). Niestety, komunikat błędu wypisywany jest na nowym terminalu, a tmux od razu go zamyka i czyści ekran.
Próbowałem wydostać tekst poprzez przekierowanie wyjścia, poprzez logi tmuksa, nie udało się nawet przy pomocy strace (!). Dopiero #asciinema dało radę.
Kolejne zastosowanie dla tego świetnego programu. Szczerze polecam!
Issue description After rebuilding tmux against libevent-2.2.1-alpha (we're testing to catch early issues), tmux is crashing immediately after opening a new session, with the following assertion: /...
#tmux crashes with #libevent 2.2.1 (alpha). However, the assertion message only gets printed inside the new terminal, and tmux closes it immediately and clears the screen.
I couldn't manage to get the message via redirecting output, via tmux logs, even via strace (!). Finally, I've figured out to use #asciinema.
Another great use case for this great program. Kudos!
Issue description After rebuilding tmux against libevent-2.2.1-alpha (we're testing to catch early issues), tmux is crashing immediately after opening a new session, with the following assertion: /...
Today's #Gentoo fun:
tmux fails to build with #libevent 2.2.1. It fails because of incompatible declaration of forkpty() in compat.h.
Looking into compat.h. forkpty() is declared there if HAVE_FORKPTY is false.
Looking into config.log. forkpty() is not found because configure tries to link random test programs to -levent_core@CMAKE_DEBUG_POSTFIX@.
At this point, you can guess what the problem is: https://github.com/libevent/libevent/issues/1459
To reproduce: $ ./autogen.sh $ ./configure -C $ grep POSTFIX *.pc libevent_core.pc:Libs: -L${libdir} -levent_core@CMAKE_DEBUG_POSTFIX@ libevent_extra.pc:Libs: -L${libdir} -levent_extra@CMAKE_DEBUG_...
#glibc 2.36 introduces arc4random(). This makes #libevent switch from bundled to system ARC4 when rebuilt. Good so far.
However, glibc doesn't support arc4random_addrandom(), so libevent… removes evutil_secure_rng_add_bytes() and changes its ABI, effectively breaking installed #Tor (#Gentoo is especially affected).
Upstream argues that leaving the function as no-op is bad for #security However, when it's gone, Tor just skips the call.
https://github.com/libevent/libevent/issues/1393
https://gitlab.torproject.org/tpo/core/tor/-/blob/main/src/lib/evloop/compat_libevent.c#L483-485
Hello, I'm digging up an old question about evutil_secure_rng_add_bytes. I'm maintaining the package libevent in Debian, and lately I had a failed to build from source (FTBFS) for libevent ...