Mojo::IOLoop and epoll bug?

135 views
Skip to first unread message

Andrey Khozov

unread,
Sep 9, 2015, 10:42:59 AM9/9/15
to Mojolicious
I have a strange behavior Mojo::IOLoop::Client while connect to localhost when it resolves in two addresses.

$ host localhost
localhost has address 127.0.0.1
localhost has IPv6 address ::1
$

When using EV via select or poll or Mojo::Reactor::Poll all is ok. But when using EV via epoll I get the error "connect timeout".

$ LIBEV_FLAGS=2 strace perl -MMojo::IOLoop -le 'Mojo::IOLoop->client({address => "localhost", port => 27017}, sub { my ($l, $err, $stream) = @_; warn $err;  Mojo::IOLoop->stop }); Mojo::IOLoop->start'
socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP) = 3
...
connect(3, {sa_family=AF_INET6, sin6_port=htons(27017), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = -1 EINPROGRESS (Operation now in progress)
fcntl(3, F_GETFL)                       = 0x802 (flags O_RDWR|O_NONBLOCK)
poll([{fd=5, events=POLLIN}, {fd=3, events=POLLOUT}], 2, 9996) = 1 ([{fd=3, revents=POLLOUT|POLLERR|POLLHUP}])
getsockopt(3, SOL_SOCKET, SO_ERROR, [111], [4]) = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 4
...
dup2(4, 3)                              = 3
close(4)                                = 0
fcntl(3, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
connect(3, {sa_family=AF_INET, sin_port=htons(27017), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
poll([{fd=5, events=POLLIN}, {fd=3, events=POLLOUT}], 2, 9996) = 1 ([{fd=3, revents=POLLOUT}])
getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
connect(3, {sa_family=AF_INET, sin_port=htons(27017), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
getpeername(3, {sa_family=AF_INET, sin_port=htons(27017), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
setsockopt(3, SOL_TCP, TCP_NODELAY, [1], 4) = 0
...

$ LIBEV_FLAGS=4 strace perl -MMojo::IOLoop -le 'Mojo::IOLoop->client({address => "localhost", port => 27017}, sub { my ($l, $err, $stream) = @_; warn $err if $err;  Mojo::IOLoop->stop }); Mojo::IOLoop->start'
socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP) = 3
...
connect(3, {sa_family=AF_INET6, sin6_port=htons(27017), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = -1 EINPROGRESS (Operation now in progress)
fcntl(3, F_GETFL)                       = 0x802 (flags O_RDWR|O_NONBLOCK)
epoll_ctl(5, EPOLL_CTL_ADD, 3, {EPOLLOUT, {u32=3, u64=4294967299}}) = 0
epoll_wait(5, {{EPOLLOUT|EPOLLERR|EPOLLHUP, {u32=3, u64=4294967299}}}, 64, 9996) = 1
epoll_ctl(5, EPOLL_CTL_MOD, 3, {EPOLLOUT, {u32=3, u64=4294967299}}) = 0
getsockopt(3, SOL_SOCKET, SO_ERROR, [111], [4]) = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 4
...
dup2(4, 3)                              = 3
close(4)                                = 0
fcntl(3, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
connect(3, {sa_family=AF_INET, sin_port=htons(27017), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
epoll_wait(5, {}, 64, 9995)             = 0
write(2, "Connect timeout at -e line 1, <D"..., 48Connect timeout at -e line 1, <DATA> line 2231.
...


I see that the second time epoll_wait is not monitoring the descriptor(3) and therefore a connect event is missing.
Can you explain me this behavior?


--
Andrey Khozov

Jan Henning Thorsen

unread,
Sep 10, 2015, 8:20:17 AM9/10/15
to Mojolicious
I've experienced the same issue: https://github.com/jhthorsen/mojo-redis2/issues/12

I think this is an EV issue, which can't be fixed by Mojolicious. I could be wrong though.

sri

unread,
Sep 10, 2015, 8:25:32 AM9/10/15
to Mojolicious
I've experienced the same issue: https://github.com/jhthorsen/mojo-redis2/issues/12

Also confirmed on OS X with kqueue. Everything works fine with MOJO_NO_NDN=1, so i assume there's a problem with the file descriptor used by Net::DNS::Native to signal activity.

--
sebastian 

Andrey Khozov

unread,
Sep 10, 2015, 8:34:23 AM9/10/15
to Mojolicious
I think that Net::DNS::Native does not affect to this problem. I have not installed the Net::DNS::Native and get the same behavior also with 
MOJO_NO_NDN=1.

--
You received this message because you are subscribed to the Google Groups "Mojolicious" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mojolicious...@googlegroups.com.
To post to this group, send email to mojol...@googlegroups.com.
Visit this group at http://groups.google.com/group/mojolicious.
For more options, visit https://groups.google.com/d/optout.



--
Andrey Khozov

Andrey Khozov

unread,
Sep 10, 2015, 8:50:23 AM9/10/15
to Mojolicious
​I even tried to use the module Mojo::Reactor::UV, which is not in use EV, but have the same behavior.

On Thu, Sep 10, 2015 at 5:20 PM, Jan Henning Thorsen <jan.h...@thorsen.pm> wrote:
I think this is an EV issue, which can't be fixed by Mojolicious. I could be wrong though.

​​



--
Andrey Khozov

sri

unread,
Sep 10, 2015, 8:54:39 AM9/10/15
to Mojolicious
Also confirmed on OS X with kqueue.

Actually i was wrong, because now i can't replicate the problem anymore.

--
sebastian 

Jan Henning Thorsen

unread,
Sep 10, 2015, 8:57:38 AM9/10/15
to Mojolicious
I cannot replicate the issue I "fixed" in Mojo::Redis2 without EV installed.

Oleg

unread,
Sep 15, 2015, 7:23:46 AM9/15/15
to Mojolicious
I think dup2() inside IO::Socket::IP may cause this problem: https://metacpan.org/source/PEVANS/IO-Socket-IP-0.37/lib/IO/Socket/IP.pm#L916
socket 3 was added to epoll, then socket 4 was duplicated to socket 3, I think epoll may not like this: http://stackoverflow.com/questions/27948251/why-epoll-wait-doesnt-react-on-dup2writable-fd-non-writable-fd

sri

unread,
Sep 15, 2015, 10:05:37 AM9/15/15
to Mojolicious
Allright, so we know what needs to be done.


The handle needs to be removed from the reactor before the ->connect call, and readded afterwards. Unfortunately we have no test case to actually replicate the problem, so this cannot be done yet.

--
sebastian

sri

unread,
Sep 15, 2015, 11:38:16 AM9/15/15
to Mojolicious
Here's a first attempt at making it work.


--
sebastian
Reply all
Reply to author
Forward
0 new messages