On Sat, Jul 26, 2008 at 10:57 PM, Roger Pack < roger.pack at leadmediapartners.com> wrote:> Also the revem stuff works now, as least it does for my project. > Which is good news for me :) > Rev also seems to show more stability than EM > and possibly even a bit more speedThat''s awesome... Rev''s main bottleneck now is with applications that open and close TCP connections rapidly. Is your application using persistent connections?> Anyway take a look at the modifications. They seem to work, though I > wouldn''t think of it as ideal by any means.I''ll take a look and see if there''s anything that I can clean up> Also fixed some weird bug where if you had Ehost::UNREACH thrown for > DNS it would err. I wasn''t able to surround it with a rescue block in > the calling function [which would be cleaner] for some reason. Kind > of bizarre. Oh well.Interesting, well hopefully those things get handled internally by Rev as much as possible. I assume that''s what you did?> Thanks again. > Hopefully this will overcome those silly kqueue errors that EM has > currently :) >libev should be fairly rock solid with kqueue support (at least compared to EM). -- Tony Arcieri medioh.com -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rev-talk/attachments/20080727/32240f81/attachment-0001.html>
On Mon, Jul 28, 2008 at 4:02 AM, Roger Pack < roger.pack at leadmediapartners.com> wrote:> Also if /etc/resolv.conf isn''t found should it raise or just call > on_connect_failed? I assume the latter? >I really think it should raise Errno::ENOENT for /etc/resolv.conf. If it''s missing that represents a serious system misconfiguration error that should crash the program. The latter is more in the style of EM, which is to swallow errors and handle them in ways that make programs difficult to debug (such as the infamous EM::ConnectionNotBound). I can see the argument for it being treated like other DNS resolution errors, but if someone''s actually on a system that uses a DNS resolution scheme which doesn''t rely on /etc/resolv.conf they''ll have an awfull hard time figuring out what the problem is. In other news, wouldn''t it be slightly more efficient to do something> event_callback''ed methods being defined as > def method_name *args > return unless @_method_name_is_setup > @_method_name_block.call *args > end > > def method_name_do &block > @_method_name_is_setup = true > @_method_name_block = &block > end > > Then it wouldn''t have to check for [and have named blocks] for every > method call.You''re right that it''s probably slow to be capturing the block as a Proc every time for every callback that the user never defines in a subclass. Subclasses are still going to be the way to get the best speed, so it''s pointless to slow them down with a different style that no one''s going to use. However, I''m really starting to think that syntax isn''t worth the hassle. While it''s slightly better looking, it''s slower and obviously instance_exec that''s needed for things like on_connect and on_read isn''t supported in Ruby 1.8 without crazy hacks. Also by several people''s accounts it''s broken even on Ruby 1.9. Maybe it''d be best if I just got rid of it and required people to use subclasses. Also, your example doesn''t provide any way to get to the IO / Server object itself... you could unshift it onto the args array, but then you always have to receive the connection object as a parameter, which in my opinion isn''t a whole lot better than subclassing, and would still be quite a bit slower. Now in regards to magic:> > would this: > > class Tester < Rev::TCPSocket > end > Tester.new(''google.com'', 80) # make more sense for people? > or maybe > Tester.create(''google.com'', 80) ? >Yes. Those sorts of things are possible now that Rev::IO is no longer a subclass of Rev::IOWatcher. There''s some ugliness that crept into the API thanks to that extraordinarily bad decision. I think now that it''s been fixed it''s probably time to take a step back and look at what can be cleaned up. Also thoughts on having the default event loop as> Rev::Loop.default--that might be handy, too > a = TCPSocket.connect("google.com", 80).attach # has a default. >That''s a great idea. -- Tony Arcieri medioh.com -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rev-talk/attachments/20080728/423db5c1/attachment.html>
> I really think it should raise Errno::ENOENT for /etc/resolv.conf. If it''s > missing that represents a serious system misconfiguration error that should > crash the program. The latter is more in the style of EM, which is to > swallow errors and handle them in ways that make programs difficult to debug > (such as the infamous EM::ConnectionNotBound). I can see the argument for > it being treated like other DNS resolution errors, but if someone''s actually > on a system that uses a DNS resolution scheme which doesn''t rely on > /etc/resolv.conf they''ll have an awfull hard time figuring out what the > problem is.Either way''s fine. The only time I ran into it was when I had some flaky wireless [and OS X deletes /etc/resolv.conf when you don''t have a connection]. What about if you send a packet in the direction of a "previously good" DNS server and receive Errno::EHOSTUNREACH--same thing?>> In other news, wouldn''t it be slightly more efficient to do something >> event_callback''ed methods being defined as >> def method_name *args >> return unless @_method_name_is_setup >> @_method_name_block.call *args >> end >> >> def method_name_do &block >> @_method_name_is_setup = true >> @_method_name_block = &block >> end >> >> Then it wouldn''t have to check for [and have named blocks] for every >> method call. > > You''re right that it''s probably slow to be capturing the block as a Proc > every time for every callback that the user never defines in a subclass. > Subclasses are still going to be the way to get the best speed, so it''s > pointless to slow them down with a different style that no one''s going to > use. > > However, I''m really starting to think that syntax isn''t worth the hassle. > While it''s slightly better looking, it''s slower and obviously instance_exec > that''s needed for things like on_connect and on_read isn''t supported in Ruby > 1.8 without crazy hacks. Also by several people''s accounts it''s broken even > on Ruby 1.9.I will admit the only I might dislike it is the fear instilled in me by trying to get it to work recently in 1.8.6 with those weird errors I reported. LOL. I totally ducked that one. Haven''t even gone back to touch it and try and fix it, since. Either instance_exec is wrong or something is seriously hosed. Maybe what you can instead do is not use it internally [it''s only used what a very few times currently, internally, I guess], then perhaps create a class like TCPSocketFlexible or TCPSocketUserDefinable < Rev::TCPSocket that has the functionality that it offers. That type of functionality is not bad or unwelcome. I wrote a similar class in EM [though not as pretty], and imagine almost everyone has need for some light weight protocols. Similar as in it used arbitrary blocks for message handlers, that''s it. The speed difference is probably miniscule and a premature optimization, since the real bottleneck is probably having the socket creation and event binding in Ruby instead of in C :) I am continually amazed by how slow Ruby is compared to C.> Maybe it''d be best if I just got rid of it and required people to use > subclasses. > > Also, your example doesn''t provide any way to get to the IO / Server object > itself... you could unshift it onto the args array, but then you always have > to receive the connection object as a parameter, which in my opinion isn''t a > whole lot better than subclassing, and would still be quite a bit slower.yeah I forgot the instance_exec necessary for the example code. It should have it. My bad.>> Now in regards to magic: >> >> would this: >> >> class Tester < Rev::TCPSocket >> end >> Tester.new(''google.com'', 80) # make more sense for people? >> or maybe >> Tester.create(''google.com'', 80) ? > > Yes. Those sorts of things are possible now that Rev::IO is no longer a > subclass of Rev::IOWatcher. > > There''s some ugliness that crept into the API thanks to that extraordinarily > bad decision. I think now that it''s been fixed it''s probably time to take a > step back and look at what can be cleaned up.Please do. Reminds me of EM dogmatically sticking by the fact that post_init is called before the block, which basically makes it useless without magical constructors :) Refactoring is good. Very good. If I had my druthers I''d have Tester.new(''google.com'', 80) be the default way [since it...just makes so much sense] and Tester.new_with_existing(existing_socket) as an alternative to the normal way. But that''s just me. I''d be happy to code it up--having TCPSocket behave this way. Or maybe I''ll just have SuperTCPConnection [described below] do it :)>> Also thoughts on having the default event loop as >> Rev::Loop.default--that might be handy, too >> a = TCPSocket.connect("google.com", 80).attach # has a default. > > That''s a great idea.I''ll add it sometime, especially if I ever get the hunkering to want to be able to use it :) My latest thought is to, similar to revactor''s helpful add-ons, create something like the SuperTCPConnection < Rev::TCPSocket that includes a connection timeout and an activity timeout. To attempt to reign in the difficulties that apparently TCP presents applications. I could just add this type functionality to TCPSocket but...it seems like it might clutter TCP with a bit of functionality. I already don''t like the cluttering I had to do to get pre-DNS writing to work. That stuff could use some love. So basically I''ll create that class and then consider it good to go. Thoughts? -R
Can you CC rev-talk on your replies? On Tue, Jul 29, 2008 at 12:33 AM, Roger Pack < roger.pack at leadmediapartners.com> wrote:> Maybe what you can instead do is not use it internally [it''s only used > what a very few times currently, internally, I guess], then perhaps > create a class like > TCPSocketFlexible or TCPSocketUserDefinable < Rev::TCPSocket > that has the functionality that it offers. > That type of functionality is not bad or unwelcome. I wrote a similar > class in EM [though not as pretty], and imagine almost everyone has > need for some light weight protocols. Similar as in it used arbitrary > blocks for message handlers, that''s it.Maybe it could be a module you can include in subclasses of Rev::IO> Please do. Reminds me of EM dogmatically sticking by the fact that > post_init is called before the block, which basically makes it useless > without magical constructors :) > Refactoring is good. Very good. > > If I had my druthers I''d have Tester.new(''google.com'', 80) be the > default way [since it...just makes so much sense] and > Tester.new_with_existing(existing_socket) as an alternative to the > normal way. But that''s just me. > > I''d be happy to code it up--having TCPSocket behave this way. Or > maybe I''ll just have SuperTCPConnection [described below] do it :) >You''ll either need to change Rev::IO or have Rev::TCPSocket not descend from Rev::IO. I would certainly prefer the former. A class method isn''t going to work, as you need an instance of Rev::IO to attach to the event loop. The real Ruby IO object is going to exist until DNS resolution has completed. Rev::IO would need some sort of way to instantiate it without an actual Ruby IO object associated, then another method to set the IO object later. Or subclasses could just override initialize. So perhaps Rev::IO#ruby_io= ? My latest thought is to, similar to revactor''s helpful add-ons, create> something like the SuperTCPConnection < Rev::TCPSocket > that includes a connection timeout and an activity timeout. To > attempt to reign in the difficulties that apparently TCP presents > applications. I could just add this type functionality to TCPSocket > but...it seems like it might clutter TCP with a bit of functionality. > I already don''t like the cluttering I had to do to get pre-DNS writing > to work. That stuff could use some love. > So basically I''ll create that class and then consider it good to go. >How about a module... include Rev::TCPSocket::Timeouts ? -- Tony Arcieri medioh.com -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rev-talk/attachments/20080730/a2b1587c/attachment.html>
That''s a good idea for implementing them as modules. something like class A < Rev::TCPSocket include ConnectionTimeout include LivenessTimeout end Or Rev::TCPSocket::Timeouts or what not. I''ll think about the .new guy, as well, though that''s somewhat of a lower priority since .connect works :) -R On Wed, Jul 30, 2008 at 4:05 PM, Tony Arcieri <tony at medioh.com> wrote:> Can you CC rev-talk on your replies? > > On Tue, Jul 29, 2008 at 12:33 AM, Roger Pack > <roger.pack at leadmediapartners.com> wrote: >> >> Maybe what you can instead do is not use it internally [it''s only used >> what a very few times currently, internally, I guess], then perhaps >> create a class like >> TCPSocketFlexible or TCPSocketUserDefinable < Rev::TCPSocket >> that has the functionality that it offers. >> That type of functionality is not bad or unwelcome. I wrote a similar >> class in EM [though not as pretty], and imagine almost everyone has >> need for some light weight protocols. Similar as in it used arbitrary >> blocks for message handlers, that''s it. > > Maybe it could be a module you can include in subclasses of Rev::IO > >> >> Please do. Reminds me of EM dogmatically sticking by the fact that >> post_init is called before the block, which basically makes it useless >> without magical constructors :) >> Refactoring is good. Very good. >> >> If I had my druthers I''d have Tester.new(''google.com'', 80) be the >> default way [since it...just makes so much sense] and >> Tester.new_with_existing(existing_socket) as an alternative to the >> normal way. But that''s just me. >> >> I''d be happy to code it up--having TCPSocket behave this way. Or >> maybe I''ll just have SuperTCPConnection [described below] do it :) > > You''ll either need to change Rev::IO or have Rev::TCPSocket not descend from > Rev::IO. I would certainly prefer the former. > > A class method isn''t going to work, as you need an instance of Rev::IO to > attach to the event loop. The real Ruby IO object is going to exist until > DNS resolution has completed. > > Rev::IO would need some sort of way to instantiate it without an actual Ruby > IO object associated, then another method to set the IO object later. Or > subclasses could just override initialize. > > So perhaps Rev::IO#ruby_io= ? > >> My latest thought is to, similar to revactor''s helpful add-ons, create >> something like the SuperTCPConnection < Rev::TCPSocket >> that includes a connection timeout and an activity timeout. To >> attempt to reign in the difficulties that apparently TCP presents >> applications. I could just add this type functionality to TCPSocket >> but...it seems like it might clutter TCP with a bit of functionality. >> I already don''t like the cluttering I had to do to get pre-DNS writing >> to work. That stuff could use some love. >> So basically I''ll create that class and then consider it good to go. > > How about a module... include Rev::TCPSocket::Timeouts ? > > -- > Tony Arcieri > medioh.com >