From tony at medioh.com Thu Jul 3 19:07:18 2008 From: tony at medioh.com (Tony Arcieri) Date: Thu, 3 Jul 2008 17:07:18 -0600 Subject: [Rev-talk] revem In-Reply-To: <966599840807031602x4ad0e373j1c3e9fc500565d29@mail.gmail.com> References: <966599840807031602x4ad0e373j1c3e9fc500565d29@mail.gmail.com> Message-ID: On Thu, Jul 3, 2008 at 5:02 PM, Roger Pack wrote: > I assume it's ok to have revem.rb require 'eventmachine'? > -R > Yep. Go nuts with revem. My real hope for revem is that we can turn it into a sort of generic EventMachine compatibility layer for Rev-like APIs. I plan on implementing a Rev-like API for Rubinius that uses Scheduler/Channels, so hopefully revem can also target that and allow running EventMachine applications on top of Rubinius. -- Tony Arcieri medioh.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From tony at medioh.com Thu Jul 3 19:09:46 2008 From: tony at medioh.com (Tony Arcieri) Date: Thu, 3 Jul 2008 17:09:46 -0600 Subject: [Rev-talk] patches for rev In-Reply-To: <966599840807031601w6958c11nc6809434b9e14299@mail.gmail.com> References: <966599840806281118h4ffb23b6l75476abaf3b4f45a@mail.gmail.com> <966599840806281422n5d1f9c00o525c8a2365c0dd7a@mail.gmail.com> <966599840806281644u62130cebp7228d22d5c14b15@mail.gmail.com> <966599840806281656i577a6e92s945ca079a71ecb06@mail.gmail.com> <966599840806282059w1c9599e9hdb82aa4cd34f5289@mail.gmail.com> <966599840807031601w6958c11nc6809434b9e14299@mail.gmail.com> Message-ID: On Thu, Jul 3, 2008 at 5:01 PM, Roger Pack wrote: > Is that the case if you've defined on_write_complete in the child class? > Nope. This would have the rather confusing behavior of you actually calling your own on_write_complete method. Generally I would assume if you've defined your own on_write_complete behavior you can handle closing the connection inside of it yourself. I generally store the current connection state as an instance variable and use that to make decisions about what behaviors to execute in the callbacks. Have a look at the Rev HTTP client for an example (although it doesn't use on_write_complete). -- Tony Arcieri medioh.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From roger.pack at leadmediapartners.com Fri Jul 25 01:55:38 2008 From: roger.pack at leadmediapartners.com (Roger Pack) Date: Thu, 24 Jul 2008 23:55:38 -0600 Subject: [Rev-talk] weirdness Message-ID: <966599840807242255xe790ef3o95435009ce785edc@mail.gmail.com> As a note, if I run the instance_exec echo server, I get some weirdness. The code works and it does echo, but on_connect doesn't seem to ever work. If I add in a print statement to the def event_callback(*methods) methods.each do |method| module_eval <<-EOD def #{method}(*args, &block) print "within it#{method}\n" I get Echo server listening on 127.0.0.1:4321 within iton_connect within iton_connect within iton_close within iton_read with a single read. Not quite sure where all those are coming from, but hey. I may look into it sometime. The 'normal' echo server in examples/echo_server works as expected, though. Also as a note, with revem we 'used to' "re super class" the Connection class. These days it appears to throw TypeError: superclass mismatch [I think--it's been awhile] So will attempt to redo it. Thanks! -R From roger.pack at leadmediapartners.com Fri Jul 25 03:30:27 2008 From: roger.pack at leadmediapartners.com (Roger Pack) Date: Fri, 25 Jul 2008 01:30:27 -0600 Subject: [Rev-talk] weirdness In-Reply-To: <966599840807242255xe790ef3o95435009ce785edc@mail.gmail.com> References: <966599840807242255xe790ef3o95435009ce785edc@mail.gmail.com> Message-ID: <966599840807250030r5394416am59b73ab5db1f8f5f@mail.gmail.com> Also I assume that we keep track of timers in memory somewhere so they don't get collected? :) Thanks. -R From roger.pack at leadmediapartners.com Fri Jul 25 04:40:28 2008 From: roger.pack at leadmediapartners.com (Roger Pack) Date: Fri, 25 Jul 2008 02:40:28 -0600 Subject: [Rev-talk] revem Message-ID: <966599840807250140r23d9701due57c9e50b52154db@mail.gmail.com> K I made some progress on revem [checked in as contrib/revem2]. Actually runs the echo server, and does timeouts. The current barrier seems to be if I do a write on a Rev::TCPSocket before it has connected to the other host [DNS might cause a similar error--this example was just using IP addresses]. I believe that's what's happening. Any thoughts? -R From tony at medioh.com Fri Jul 25 12:25:52 2008 From: tony at medioh.com (Tony Arcieri) Date: Fri, 25 Jul 2008 10:25:52 -0600 Subject: [Rev-talk] weirdness In-Reply-To: <966599840807242255xe790ef3o95435009ce785edc@mail.gmail.com> References: <966599840807242255xe790ef3o95435009ce785edc@mail.gmail.com> Message-ID: On Thu, Jul 24, 2008 at 11:55 PM, Roger Pack < roger.pack at leadmediapartners.com> wrote: > As a note, if I run the instance_exec echo server, I get some > weirdness. There seems to be lots of weirdness with the instance_exec syntax. You're really convincing me of the need for specs. I get > Echo server listening on 127.0.0.1:4321 > within iton_connect > within iton_connect > within iton_close > within iton_read > So on_connect fires twice, and read fires after close? Very weird. > Also as a note, with revem we 'used to' "re super class" the > Connection class. These days it appears to throw > > TypeError: superclass mismatch [I think--it's been awhile] > How were you attempting to do it? Can you give me a code snippet? Also I assume that we keep track of timers in memory somewhere so they > don't get collected? :) > All watchers that are attached to a given loop are added to what is, for now, an array which is an ivar within the loop object so they don't get garbage collected. An array is a poor choice for that structure algorithmically and right now is Rev's #1 performance bottleneck for things like HTTP servers that receive lots of short lived connections, as it makes Rev::Loop#detach O(n) for n connections, as Array#delete is O(n). I've tried to replace it with a "bag" type data structure which isn't order-preserving and would be O(1) in all cases, but I was trying to do it in C and couldn't get the implementation correct. -- Tony Arcieri medioh.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From tony at medioh.com Fri Jul 25 12:27:56 2008 From: tony at medioh.com (Tony Arcieri) Date: Fri, 25 Jul 2008 10:27:56 -0600 Subject: [Rev-talk] revem In-Reply-To: <966599840807250140r23d9701due57c9e50b52154db@mail.gmail.com> References: <966599840807250140r23d9701due57c9e50b52154db@mail.gmail.com> Message-ID: On Fri, Jul 25, 2008 at 2:40 AM, Roger Pack < roger.pack at leadmediapartners.com> wrote: > K I made some progress on revem [checked in as contrib/revem2]. > Actually runs the echo server, and does timeouts. Awesome > The current barrier seems to be if I do a write on a Rev::TCPSocket > before it has connected to the other host [DNS might cause a similar > error--this example was just using IP addresses]. I believe that's > what's happening. > Any thoughts? > You might try buffering data in a string until the connection completes or errors. Otherwise I can look at making write work in this case. -- Tony Arcieri medioh.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From tony at medioh.com Fri Jul 25 17:22:19 2008 From: tony at medioh.com (Tony Arcieri) Date: Fri, 25 Jul 2008 15:22:19 -0600 Subject: [Rev-talk] weirdness In-Reply-To: <966599840807251345n9cbb68ewf0c82c3fa65188eb@mail.gmail.com> References: <966599840807242255xe790ef3o95435009ce785edc@mail.gmail.com> <966599840807251345n9cbb68ewf0c82c3fa65188eb@mail.gmail.com> Message-ID: On Fri, Jul 25, 2008 at 2:45 PM, Roger Pack < roger.pack at leadmediapartners.com> wrote: > My attempt is to > require 'eventmachine' > then 'monkey patch' it to use rev for the actual connections. > Which quickly yielded: > > ~/dev/rev_committable/contrib/revem ruby revem.rb > revem.rb:49: superclass mismatch for class Connection (TypeError) > > So I'm working on the revem2.rb which is in there currently. > The benefit of this is that you can use things like EM::Timer 'without > changing its code at all' [which class I use in my existing app]. > That's the goal, anyway :) > Aah. I had never tried loading revem and eventmachine at the same time, but now I see why it would be problematic. Feel free to modify revem directly. You don't need to make a revem2. > I asume the code works such that it doesn't create a 'real' tcpsocket > class [with write buffer] until the connection completes. Actually, it does. I'll need to look more in depth as to why this isn't working. Can you send me the error you were getting? So it's ok > to just create the write buffer early, but then I get confused about > the writer being attached to the event loop, and how it seems like the > reader is attached [only] to the event loop and such. The write watcher is only attached to the event loop when there's data in the write buffer. > And how sockets, when you create them 'auto bind' to the current event > loop. Is that right? No. You need to attach any subclass of Rev::IO (including Sockets) to the event loop explicitly. > Incoming sockets from acceptors 'auto bind' to the current event loop. > And tcp sockets also need to bind to an event loop? > If you're using something like Rev::TCPServer then yes, the newly created connection objects are automatically bound to the same loop the server is attached to. > Yeah. Once it's working then maybe will look at performance :) > There's lots of opportunities for performance improvements. I'd really like to look at doing simple proactor objects in C that work like IOWatchers but actually perform the I/O completely in C when readiness is signaled. Right now performing I/O involves quite a few rb_funcalls -- Tony Arcieri medioh.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From tony at medioh.com Fri Jul 25 18:21:21 2008 From: tony at medioh.com (Tony Arcieri) Date: Fri, 25 Jul 2008 16:21:21 -0600 Subject: [Rev-talk] weirdness In-Reply-To: <966599840807251503s59f36af1k452fc63fb24b53f7@mail.gmail.com> References: <966599840807242255xe790ef3o95435009ce785edc@mail.gmail.com> <966599840807251345n9cbb68ewf0c82c3fa65188eb@mail.gmail.com> <966599840807251503s59f36af1k452fc63fb24b53f7@mail.gmail.com> Message-ID: On Fri, Jul 25, 2008 at 4:03 PM, Roger Pack < roger.pack at leadmediapartners.com> wrote: > I see that it does. But just doesn't create the write buffer until later. > I tried creating the write buffer early but...I think the error then > was that if I called write before the 'real connection' had been > established: > > /Users/rogerpack/dev/rev_committable/trunk/lib/rev/io.rb:142:in > `enable_write_watcher': undefined method `attached?' for nil:NilClass > (NoMethodError) > from /Users/rogerpack/dev/rev_committable/trunk/lib/rev/io.rb:136:in > `schedule_write' > from /Users/rogerpack/dev/rev_committable/trunk/lib/rev/io.rb:81:in > `write' > from ./lib/opendht/../../revem.rb:147:in `send_data' Aah, so the real problem is the connection objects aren't "fully" initialized until the connection completes. Furthermore, Rev does async DNS. This means that there actually isn't a TCP socket to write to at all until the DNS lookup completes. If you want to support this behavior, you'll really need to make an internal buffer that's used until the connection is fully established. Yeah that would for sure make sense with [for example] an internal > write watcher. Problematic would only be its calling > 'on_write_complete' when its done. But if you gave it a hash for its > call-back object you'd be good. > Well, instead of it having an on_writable callback as the present Reactor objects, the watcher itself would have an on_write_complete which could in turn call the on_write_complete method for the Rev::IO object. > I guess the only difference between EM and Rev [that I can see] is > that Rev uses ruby calls for reading the incoming data and creating > the sockets. Move that to C and hopefully it would be the same speed. > Theoretically. That's the hope, anyway. > Do what you can I guess :) I personally prefer it in Ruby since hacking on > C is painful and scary. > Yeah, my goal would be to do the absolute bare minimum amount of C I can while still being performant. This would involve rewriting the Rev::IO::Watcher class in C and moving some of the logic from Rev::IO into it (specifically the write buffering). -- Tony Arcieri medioh.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From roger.pack at leadmediapartners.com Fri Jul 25 19:14:39 2008 From: roger.pack at leadmediapartners.com (Roger Pack) Date: Fri, 25 Jul 2008 17:14:39 -0600 Subject: [Rev-talk] weirdness In-Reply-To: References: <966599840807242255xe790ef3o95435009ce785edc@mail.gmail.com> <966599840807251345n9cbb68ewf0c82c3fa65188eb@mail.gmail.com> <966599840807251503s59f36af1k452fc63fb24b53f7@mail.gmail.com> Message-ID: <966599840807251614l3c56c2e1lb21485f36ef9cc94@mail.gmail.com> Question: Can you think why on_connect_failed is being called with this? It just starts up a 'normal' TCP Server, and connects to it. ? require File.dirname(__FILE__) + '/../../trunk/lib/rev' #require 'rubygems' #require 'rev' ADDR = '127.0.0.1' PORT = 4321 require 'socket' a = TCPServer.new ADDR, PORT # one that won't resolve your connections class ClientConnection < Rev::TCPSocket def on_connect puts "#{remote_addr}:#{remote_port} connected" write "bounce this back to me" end def on_close puts "#{remote_addr}:#{remote_port} disconnected" end def on_read(data) print "got #{data}" close end def on_connect_failed print "WHY do we get here" end end event_loop = Rev::Loop.default a = ClientConnection.connect(ADDR, PORT) a.attach a.write "yep" puts "Echo client started to #{ADDR}:#{PORT}" event_loop.run From tony at medioh.com Sun Jul 27 23:39:47 2008 From: tony at medioh.com (Tony Arcieri) Date: Sun, 27 Jul 2008 21:39:47 -0600 Subject: [Rev-talk] latest changes In-Reply-To: <966599840807262157i27cceabbs82fab7df3809fff7@mail.gmail.com> References: <966599840807262157i27cceabbs82fab7df3809fff7@mail.gmail.com> Message-ID: 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 speed That'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: From roger.pack at leadmediapartners.com Mon Jul 28 11:25:18 2008 From: roger.pack at leadmediapartners.com (Roger Pack) Date: Mon, 28 Jul 2008 09:25:18 -0600 Subject: [Rev-talk] nagle Message-ID: <966599840807280825n285ac347t952a066cd4269d86@mail.gmail.com> is nagle disabled? Do we want to do that? What about SO_KEEPALIVE SO_REUSEADDR and possibly even SO_SNDBUF [?] Thanks. -R From tony at medioh.com Mon Jul 28 13:34:49 2008 From: tony at medioh.com (Tony Arcieri) Date: Mon, 28 Jul 2008 11:34:49 -0600 Subject: [Rev-talk] nagle In-Reply-To: <966599840807280825n285ac347t952a066cd4269d86@mail.gmail.com> References: <966599840807280825n285ac347t952a066cd4269d86@mail.gmail.com> Message-ID: On Mon, Jul 28, 2008 at 9:25 AM, Roger Pack < roger.pack at leadmediapartners.com> wrote: > is nagle disabled? Do we want to do that? > What about > SO_KEEPALIVE > SO_REUSEADDR and possibly even SO_SNDBUF [?] > Well, one thing we could do is provide a key in the options hash for socket options when creating TCPSockets and TCPServers, then provide a set of defaults. I could've sworn I was setting Socket::SO_REUSEADDR on TCPServers, but apparently I was not. Oddly enough I've never encountered problems with it in my TCP servers using Rev... -- Tony Arcieri medioh.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From roger.pack at leadmediapartners.com Mon Jul 28 15:20:12 2008 From: roger.pack at leadmediapartners.com (Roger Pack) Date: Mon, 28 Jul 2008 13:20:12 -0600 Subject: [Rev-talk] nagle In-Reply-To: <966599840807280825n285ac347t952a066cd4269d86@mail.gmail.com> References: <966599840807280825n285ac347t952a066cd4269d86@mail.gmail.com> Message-ID: <966599840807281220k312cf43x3ae09f47e23e4b04@mail.gmail.com> Couple of thoughts: One thought for rev would be to have a single generic fail function---like on_resolve_failed calls it by default, same with on_connect_failed, if they're not yet defined. maybe call it. on_any_failure or something :) In reality it's not a big deal to have the nicely verbose error messages--it's just barely confusing for newer users. I would say just use on_close for it, but I'm not sure if that's what we'd want or not. Anyway just thinking out loud. With the revem for some reason when I add a connection timer outer it ends up closing my server socket. Very very odd--unless starting a server also calls Socket.connect [which it doesn't that I'm aware of] :) Then there's this odd case in [at least] OS X still where TCP appears to just give up on a connection half-way through if it's faced with a period of intense congestion. It never reconnects! Ahh! Any ideas on why that might be happening? Recreatable with EM, too. Man I had assumed TCP would hold my hand with annoyances like this. Apparently I was wrong. I think that it's just that the ACK's are getting lost and then the ACK'ed ACK's are getting lost or something, but why it doesn't keep retrying is beyond me. adding TCP_NODELAY and SO_KEEPALIVE seem to not fix it. I guess the only answer is to add a connect timer [for lost SYN's]. And also a read timeout or something when you expect input. Ahh well. =R On Mon, Jul 28, 2008 at 9:25 AM, Roger Pack wrote: > is nagle disabled? Do we want to do that? > What about > SO_KEEPALIVE > SO_REUSEADDR and possibly even SO_SNDBUF [?] > > Thanks. > -R > From tony at medioh.com Mon Jul 28 15:34:32 2008 From: tony at medioh.com (Tony Arcieri) Date: Mon, 28 Jul 2008 13:34:32 -0600 Subject: [Rev-talk] nagle In-Reply-To: <966599840807281220k312cf43x3ae09f47e23e4b04@mail.gmail.com> References: <966599840807280825n285ac347t952a066cd4269d86@mail.gmail.com> <966599840807281220k312cf43x3ae09f47e23e4b04@mail.gmail.com> Message-ID: On Mon, Jul 28, 2008 at 1:20 PM, Roger Pack < roger.pack at leadmediapartners.com> wrote: > Couple of thoughts: > One thought for rev would be to have a single generic fail > function---like on_resolve_failed calls it by default, same with > on_connect_failed, if they're not yet defined. maybe call it. > on_any_failure or something :) > > In reality it's not a big deal to have the nicely verbose error > messages--it's just barely confusing for newer users. > I would say just use on_close for it, but I'm not sure if that's what > we'd want or not. > Anyway just thinking out loud. > There could be a generic on_failure, but I'd like to keep the rb_funcalls to a minimum. > With the revem for some reason when I add a connection timer outer it > ends up closing my server socket. Very very odd--unless starting a > server also calls Socket.connect [which it doesn't that I'm aware of] That's pretty odd. Revactor creates timer objects for every single read / write, and I've used it in conjunction with Mongrel and ran ApacheBench against it (Revactor comes up as slower than both Evented Mongrel and Thin, due mainly to the speed problems with detach). Can you pastie a code snippet that causes the problem? > Then there's this odd case in [at least] OS X still where TCP appears > to just give up on a connection half-way through if it's faced with a > period of intense congestion. It never reconnects! Ahh! Any ideas on > why that might be happening? Recreatable with EM, too. Man I had > assumed TCP would hold my hand with annoyances like this. Apparently > I was wrong. I've never encountered a problem like that, and the main thing I use Rev for is a massively concurrent HTTP fetcher, which I test somewhat regularly on OS X. In fact, it makes connections so fast that it actually overwhelms the NAT implementation on our router before it overwhelms the TCP stack on OS X. -- Tony Arcieri medioh.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From tony at medioh.com Tue Jul 29 00:07:05 2008 From: tony at medioh.com (Tony Arcieri) Date: Mon, 28 Jul 2008 22:07:05 -0600 Subject: [Rev-talk] latest changes In-Reply-To: <966599840807280302s7a897cd2u398207118852121c@mail.gmail.com> References: <966599840807262157i27cceabbs82fab7df3809fff7@mail.gmail.com> <966599840807280302s7a897cd2u398207118852121c@mail.gmail.com> Message-ID: 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: From roger.pack at leadmediapartners.com Tue Jul 29 02:33:57 2008 From: roger.pack at leadmediapartners.com (Roger Pack) Date: Tue, 29 Jul 2008 00:33:57 -0600 Subject: [Rev-talk] latest changes In-Reply-To: References: <966599840807262157i27cceabbs82fab7df3809fff7@mail.gmail.com> <966599840807280302s7a897cd2u398207118852121c@mail.gmail.com> Message-ID: <966599840807282333y36ba1cbcu97dc0a350b4f9623@mail.gmail.com> > 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 From tony at medioh.com Wed Jul 30 18:05:16 2008 From: tony at medioh.com (Tony Arcieri) Date: Wed, 30 Jul 2008 16:05:16 -0600 Subject: [Rev-talk] latest changes In-Reply-To: <966599840807282333y36ba1cbcu97dc0a350b4f9623@mail.gmail.com> References: <966599840807262157i27cceabbs82fab7df3809fff7@mail.gmail.com> <966599840807280302s7a897cd2u398207118852121c@mail.gmail.com> <966599840807282333y36ba1cbcu97dc0a350b4f9623@mail.gmail.com> Message-ID: 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: From roger.pack at leadmediapartners.com Thu Jul 31 17:16:39 2008 From: roger.pack at leadmediapartners.com (Roger Pack) Date: Thu, 31 Jul 2008 15:16:39 -0600 Subject: [Rev-talk] latest changes In-Reply-To: References: <966599840807262157i27cceabbs82fab7df3809fff7@mail.gmail.com> <966599840807280302s7a897cd2u398207118852121c@mail.gmail.com> <966599840807282333y36ba1cbcu97dc0a350b4f9623@mail.gmail.com> Message-ID: <966599840807311416y2334b528i72232341519438c0@mail.gmail.com> 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 wrote: > Can you CC rev-talk on your replies? > > On Tue, Jul 29, 2008 at 12:33 AM, Roger Pack > 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 >