Hi Naoki, It seems very interesting, thank you for your contribution. To me, it makes sense to merge this feature.
Have a nice day. -- Ludovic Gasc (GMLudo) http://www.gmludo.eu/ 2016-04-01 14:49 GMT+02:00 Naoki INADA <[email protected]>: > Hi, async programmers. > > Linux 4.5 released in last month intorduces EPOLLEXCLUSIVE. > http://man7.org/linux/man-pages/man2/epoll_ctl.2.html > > It can address epoll thundering herd problem. > > http://uwsgi-docs.readthedocs.org/en/latest/articles/SerializingAccept.html#select-poll-kqueue-epoll > > I tried it on AWS EC2 c4.xlarge (4core). > > * simple "hello world" wsgi app > * Use uWSGI and meinheld with 8 workers > * ab -n10000 -c4 > > EPOLLEXCLUSIVE improve performance from 15k req/sec to 22k req/sec. > > And I confirm it reduces number of `accept4()` call significantly. > > ubuntu:~/app$ strace -f ~/.local/bin/uwsgi --master --workers=8 --http-socket > :8080 --wsgi hello 2>trace.log > ubuntu:~$ ab -c1 -n1000 http://localhost:8080/ > ubuntu:~/app$ grep -c '] accept4' trace.log # w/o EPOLLEXCLUSIVE6884 > ubuntu:~/app$ grep -c '] accept4' trace.log # w/ EPOLLEXCLUSIVE1557 > > > > And I confirm Linux ~4.4 ignores EPOLLEXCLUSIVE (1 << 28). So I can use > it safely without compile time nor runtime check. > > I want to add EPOLLEXCLUSIVE support to asyncio. > Current selector's API is: > > abstractmethod register(fileobj, events, data=None) > > > https://docs.python.org/3/library/selectors.html#selectors.BaseSelector.register > > How can I cange the API? > > Maybe: > > abstractmethod register(fileobj, events, data=None, **flags) > ... > poller.register(listenfd, selectors.EVENT_READ, data, exclusive=True) # > only EpollSelector supports exclusive. others ignore unknown flags. > > > Or: > > poller.register(listenfd, selectors.EVENT_READ_EXCLUSIVE, data) # Add > EVENT_READ_EXCLUSIVE and EVENT_READ_EXCLUSIVE. > > > Thanks. > > --- > pache for meinheld: > > diff --git a/meinheld/server/picoev_epoll.c b/meinheld/server/picoev_epoll.c > index 06e1dbb..773cf3c 100644--- a/meinheld/server/picoev_epoll.c+++ > b/meinheld/server/picoev_epoll.c@@ -115,6 +115,7 @@ int > picoev_update_events_internal(picoev_loop* _loop, int fd, int events) > SET(EPOLL_CTL_MOD, 0); > if (epoll_ret != 0) { > assert(errno == ENOENT);+ ev.events |= (1 << 28); // > EPOLLEXCLUSIVE (from linux 4.5) > SET(EPOLL_CTL_ADD, 1); > } > }@@ -124,7 +125,12 @@ int picoev_update_events_internal(picoev_loop* > _loop, int fd, int events) > if ((events & PICOEV_READWRITE) == 0) { > SET(EPOLL_CTL_DEL, 1); > } else {- SET(target->events == 0 ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, 1);+ > if (target->events == 0) {+ ev.events |= (1 << 28); // > EPOLLEXCLUSIVE (from linux 4.5)+ SET(EPOLL_CTL_ADD, 1);+ } else {+ > SET(EPOLL_CTL_MOD, 1);+ } > } > > #endif > > > pache for uWSGI: > > diff --git a/core/event.c b/core/event.c > index 36751a6..32a1934 100644--- a/core/event.c+++ b/core/event.c@@ -514,7 > +514,7 @@ int event_queue_add_fd_read(int eq, int fd) { > struct epoll_event ee; > > memset(&ee, 0, sizeof(struct epoll_event));- ee.events = > EPOLLIN;+ ee.events = EPOLLIN | (1 << 28); > ee.data.fd = fd; > > if (epoll_ctl(eq, EPOLL_CTL_ADD, fd, &ee)) { > > >
