http keep-alive

roippi

Developer
GenericRequest does this while setting up:

Code:
systemProperties.put( "http.keepAlive", "false" );

If anyone has insight as to why this was done or why this is a good/bad thing to do, I'd like to discuss it.
 

roippi

Developer
Some more info, to perhaps stimulate a discussion:

HTTP keep-alive is a thing that keeps TCP connections open to be reused by different requests. The idea is to eliminate the TCP handshake required to open a new socket, reducing bandwidth and such. Since there are a lot of individual requests flying around in a typical mafia session (each requiring setting-up and tearing-down of a TCP socket), that seems like a good thing to have active, but this line disables it. I have it commented out in my local copy and haven't noticed any deleterious effects, though admittedly I've had time to log in perhaps ~twice in the past month.

Networking is officially Not My Thing so I'm coming from a position of ignorance - KoL's servers may not support persistent connections, or there may be some other very legitimate reason why we have it disabled. Just seeing if there's any input from devs/knowledgeable community members before I delete that line.
 

Veracity

Developer
Staff member
I wan't aware that KoLmafia reused connections.

If we opened a connection once, and then sent multiple HTTP requests over it, then I expect a keep-alive would be useful. But since we open a connection, send a single HTTP command over it, and then close it, I don't see how a keep-alive would be useful.

FWIW, Networking IS officially My Thing - but not, usually, at the Application layer, like HTTP.
 

Catch-22

Active member
I have seen this too. KoL's servers do handle persistent connections, but I believe GenericRequest would need some architectural changes before changing this setting would have any benefit.
 

roippi

Developer
Hm. I'm not so sure.

HttpURLConnection docs said:
Each HttpURLConnection instance is used to make a single request but the underlying network connection to the HTTP server may be transparently shared by other instances. Calling the close() methods on the InputStream or OutputStream of an HttpURLConnection after a request may free network resources associated with this instance but has no effect on any shared persistent connection.

My impression is that the TCP layer is somewhat abstracted from the individual objects being created to perform the requests.
 

Catch-22

Active member
I haven't noticed that in the doc before, interested me enough to give it a try.

I tried it myself, this may be a complete coincidence but my session totally died when fetching the contents of the closet during login (I can't explain why, it doesn't really make sense). Perhaps you have not noticed any deleterious effects because you may have left the part that said this.formConnection.setRequestProperty( "Connection", "close" ); in-tact. Try it without that and see if you get the same results (my login issues might be caused by something else).
 
Last edited:

roippi

Developer
I did in fact miss that. Now, with it commented out, my mafia is noticeably-to-the-naked-eye (anecdata) faster doing pretty much everything. No issues on login.

Edit: slightly more than anecdata: poking around with wireshark shows that enabling keep-alive does eliminate the TCP handshake before each request (SYN, SYN-ACK, ACK) and the cleanup afterwards (FIN-ACK, ACK). Ends up being upwards of a 20% reduction in packets sent during login (I think those are header-only packets, so bandwidth savings are miniscule, but still). Continuing to investigate.
 
Last edited:

heeheehee

Developer
Staff member
Bandwidth savings might be miniscule, but the main thing is that you're saving on roundtrips between you and the server (which noticeably improves responsiveness in short flows). Also, the final ACK of the setup can carry the HTTP request, so that one at least isn't necessarily header-only.
 

xKiv

Active member
Another idea from position of mostly ignorance: how about connections between kolmafia and the relay browser? Would keep-alive (initiated by the browser, but accepted by mafia) have any measurable good effect there? How does the handshake overhead compare between local connections (comparably high bandwidth) and internet connections (*DSL, so in the megabits/second)?
 

roippi

Developer
Another idea from position of mostly ignorance: how about connections between kolmafia and the relay browser? Would keep-alive (initiated by the browser, but accepted by mafia) have any measurable good effect there?

Yes. RelayRequests inherit from GenericRequest, so this affects them too.

How does the handshake overhead compare between local connections (comparably high bandwidth) and internet connections (*DSL, so in the megabits/second)?

The handshake in question here is between your local machine and the KoL server. So each request had a handshake overhead before it could proceed - a full roundtrip PING/PONG, basically. The issue is not one of bandwidth (miniscule) but of latency and responsiveness.
 

xKiv

Active member
The handshake in question here is between your local machine and the KoL server. So each request had a handshake overhead before it could proceed - a full roundtrip PING/PONG, basically. The issue is not one of bandwidth (miniscule) but of latency and responsiveness.

I think you are describing communication between the kolmafia process and www.kingdomofloathing.com. Are you saying handshake between firefox and 127.0.0.1:68001 doesn't matter (because it's always dominated by the kolmafia-www.kingdomofloathing.com handshake perhaps?)?
I understand the difference between bandwidth and latency, but a faster connection (like localhost-localhost) will have slightly lower latency (of the part that's interesting to an application layer) too, just because all the overhead added by lower layers will be transmitted slightly faster. Multiply by many connections.
 

roippi

Developer
Ah, I see what you're saying.

Yes, I was saying that primarily the handshake between mafia and KoL is the one you're going to notice the most - I have a ping of just about 100ms, so that's basically every request finishing 100ms faster for me.

As for the localhost interaction, I don't think this will affect communication between mafia and the browser, as such. The ServerSocket/RelayAgent/etc is distinct from GenericRequests, I don't think extraneous handshaking was going on there. Though I'm very much unsure of how to instrument it.
 

Catch-22

Active member
Happy to report I'm not getting the weird login issue from yesterday.

I did some analysis re: localhost speeds. keep-alive is working for it, I think it has always been the case. I was able to see multiple GET requests reusing the same TCP connection, so that's good.

I did notice that the relay browser adds roughly 15-20ms latency on top of the original request, that could probably be a little faster. Something else to note was that the localhost socket seems to be using an MTU of 1500, which is unnecessarily small as most OS support MTU of at least 16k on loopback interfaces.
 

heeheehee

Developer
Staff member
Is the MTU actually relevant, considering that the data is (in general) coming from KoL (where the MTU is actually limited to 1500 for "ethernet"), getting processed by Mafia, then handed off to the browser? The source of the additional latency, I imagine, is the result of proxying, especially if you have relay overrides. A smaller MTU means that you have more packets, which corresponds to overhead from headers; if you're sending packets close to the MSS (i.e. as big as you can, which you should be if a MTU of 16k makes any difference), then this is a non-issue.

And xKiv: transmission delay (where bandwidth actually comes into play: data / bandwidth) is in general irrelevant. Take a 1Mbps link, send a 128 byte packet along it; that corresponds to 1ms. If you're experiencing processing delays of 15-20ms and propagation delay on the order of 100ms, this is less than 1% of your total delay.
 

Catch-22

Active member
You shouldn't think of KoLmafia as processing things "on the wire". Basically it goes:
Browser -> KoLmafia
KoLmafia -> KoL Server
KoL Server -> KoLmafia
KoLmafia -> Browser

In other words, the communication between KoLmafia and browser can benefit from a higher MTU because the communication is completely separate to the communication being done between KoLmafia and the KoL servers.

Edit: Having said that, I am not suggesting that there would be any noticeable benefit, given that communication between loopback devices happens so quickly.
 
Last edited:

heeheehee

Developer
Staff member
My original point was that if Mafia acted purely as a forwarding proxy (which it doesn't), then it'd hand packets to the browser as soon as it got them from KoL (which might be limited to 1500), so it wouldn't be able to take advantage of a higher MTU. I know Mafia doesn't do this if a relay script is active; I'm not sure about the converse, although I'd guess this behavior doesn't change -- I assume that Mafia always waits for the entire page before passing it off to the relay browser, in which case it might make the tiniest (read: negligible) difference to use something larger than 1500. Granted, this is purely speculative on my part (regarding Mafia's inner workings), so take it with a grain of salt.
 

xKiv

Active member
My original point was that if Mafia acted purely as a forwarding proxy (which it doesn't), then it'd hand packets to the browser as soon as it got them from KoL (which might be limited to 1500), so it wouldn't be able to take advantage of a higher MTU. I know Mafia doesn't do this if a relay script is active; I'm not sure about the converse, although I'd guess this behavior doesn't change -- I assume that Mafia always waits for the entire page before passing it off to the relay browser, in which case it might make the tiniest (read: negligible) difference to use something larger than 1500. Granted, this is purely speculative on my part (regarding Mafia's inner workings), so take it with a grain of salt.

Mafia decorates pages even without relay scripts. I assume it *always* gets the whole page first, then parses (and decorates) it, and only then starts sending data to relay browser - which can be source of a great *perceived* lag (page starts displaying noticeably later; but total time until page is completely rendered is not that much higher).
 

roippi

Developer
re: MTU thing

That is another issue that's handled by the OS on some level of the IP stack - Java (and by extension Mafia) have no control over it short of fiddling with system properties.

Mafia decorates pages even without relay scripts. I assume it *always* gets the whole page first, then parses (and decorates) it, and only then starts sending data to relay browser - which can be source of a great *perceived* lag (page starts displaying noticeably later; but total time until page is completely rendered is not that much higher).

It is a good point that mafia needs to wait until the entire page arrives then process it before it can be sent to the browser. There is certainly a -lot- of string parsing and regex matching that mafia does, and on slower systems I wouldn't be surprised if it took some significant number of ms to do that.
 
Last edited:

Catch-22

Active member
Two things to add because people seem to be getting kinda hung up on what I said.

The MTU thing is pretty negligible, I was merely noting it. It's definitely causing packet fragmentation having the MTU at 1500, but localhost packets are being transferred so fast it's really not even worth getting all fussed about, just noted it based on the network traffic I saw. If it was something really easy to change, might've been worth looking into, not worth losing sleep over.

I noticed the 15-20ms processing delay was happening on hits to the api.php page (not with a "refresh status", just viewing it on my browser). I did that on purpose so there was no string processing being done and no additional images being loaded like there are on lots of other pages. It's purely a relay request, which is why I think it could be a little bit faster. Unfortunately, I can't say where it could be faster because I've only done that little bit of analysis so far.
 
Top