From cmills at freeshell.org Mon Dec 20 00:16:54 2004 From: cmills at freeshell.org (Charles Mills) Date: Mon Dec 20 00:16:17 2004 Subject: [dnssd-developers] question Message-ID: <5CBDBA1A-5246-11D9-8551-000A95A27A10@freeshell.org> I did some work on DNSSD this weekend - it has been a while - and am also in a bind about how to do the error handling. Currently certain errors are lost, for example: # if an error occurs during the call to browse, before the 'browse' thread # is started it will be raised in the binding of the caller. b = DNSSD.browse('_http._tcp') do |r| # handle discovered service end # However if an error occurs after the call to browse, but while the service 'b' is # still active (not stopped) then b's underlying thread will stop (since the error is # raised inside the thread), the block will never be called again, # but there will be no way for the client to know that an error occured. If you look at the callback implementation - dnssd_browse_reply() - an error code is passed to this callback and then checked using dnssd_check_error_code() - this raises an error if the error code is nonzero. That error is raised inside the thread - causing the thread to stop executing, ensuring that the callback will never be called again, since the thread will no longer select the socket (see dnssd_process()). So the question is what todo with that error code?? I don't think this is possible, but it would be nice if an error could be injected into the block so the following would work: b = DNSSD.browse('_http._tcp') do |r| # handle discovered service rescue DNSSD::Error # handle error end One solution that would work is to have a method that is part of the service called 'error?'. This method would check the return value of the thread using Thread#value(). If #value raises an error (which it does if there was an uncaught exception in the thread: t = Thread.new { raise "hey" } t.value #=> RuntimeError: hey ) than 'error?' return false, true otherwise. Then some way to access the error would be needed. Perhaps an 'on_error' method which takes a block and calls yield(error) whenever an error occurs. This would cause race conditions though, since the service would already be started... This doesn't seem very rubyesck so I don't like it very much... Ideas?? -Charlie