Question about integrating udns in Ruby EventMachine

Michael Tokarev mjt at tls.msk.ru
Mon Feb 7 12:34:35 MSK 2011


07.02.2011 00:46, Iñaki Baz Castillo wrote:

> - I cannot call dns_timeouts() before poll as EventMachine doesn't
> allow it to me. I just can ask EventMachine to watch in the file
> descriptor of udns and invoke dns_ioevent() when data is received. I
> can also add a periodic timer in EventMachine (useful for invoking
> dns_timeouts() periodically if required).

How it handles application timers?  There's another way to hook
udns into main loop, using a timer callback.  I never actually
did that, since I yet to see a "main loop" like this.  See
dns_set_tmcbck().

> - EventMachine also watches other file descriptors
> (TCP/UDP/UnixSocket) so I assume it doesn't block in poll, so
> "timeout" argument is 0.

If the timeout were 0 like you say, it'd be in tight loop when
nothing is happening.  It uses its own timer infrastructure to
calculate the timeout, and your job is to hook into that timer
infrastructure properly.

> I'm checking ex-rdns.c and honestly I don't understand this:
> 
>     if (curq) {
>       t = dns_timeouts(0, -1, now);
>       t = poll(&pfd, 1, c * 1000);
>       now = time(NULL);
>       if (t) dns_ioevent(0, now);
>     }
> 
> Value returned by dns_timeouts() is not used as "t" is overriden with
> poll() result in next line, neither "t" is used within poll arguments,
> do I miss something?

Yes.  This is actually yet another bug ;)  It should be the same
as I wrote in one of my previous emails, and I'll correct it right
now.  Like this:

     if (curq) {
       c = dns_timeouts(0, -1, now);
       t = poll(&pfd, 1, c < 0 ? -1 : c * 1000);
       now = time(NULL);
       if (t) dns_ioevent(0, now);
     }

And I remember I wrote it like this, maybe in another example... ;)

>>> - I've realized that, in case of a non responding DNS server (i.e:
>>> 1.2.3.4) then dns_timeouts() returns the number of second after next
>>> retransmission of the request (which is not a real timeout yet as the
>>> callback is not executed with DNS_E_TEMPFAIL). This is, my example
>>
>> The only place to use value returned by dns_timeouts() is to
>> calculate time to pass to poll/select.  There's no other usage
>> for that.
> 
> I expect you assume poll() must block for the ammount of seconds
> returned by dns_timeouts(), am I right?

Not more than that, yes.  If there are other application timers
pending, it may block for less time -- that's how you integrate
the two.

> But in my case I cannot control poll() (EventMachine does it for me).
> But I think the following can work (I would say it's lredy working in
> my code):

Um, that's somewhat ugly.  It may work, but it's over-complicated, in
my opinion.  It is difficult for me to believe that your EventMachine
does not allow one to hook into the place before poll/select (usually
they do), but even if it's so, maybe the timer callback I mentioned
above will do the trick.  It is a bit more difficult to understand
(and hence use right), however.

/mjt


More information about the udns mailing list