Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: Is SelectionKey.attach() broken?

In my implementation of Java NIO I have not been able to get SelectionKey.attach() to work. Basically, once clients connect (OP_ACCEPT interest ops) I add them to a map where their IP address maps to an object that maintains state for the client. Then, when an OP_READ occurs, I again retrieve the client's IP address, and this time get the value from the map and get the client's state object that way.

The problem here is that I have to do a map lookup EVERY TIME data is read from the network. There is a lot of wasted work going on there. So, I was thrilled to see that you can attach an arbitrary object type to a SelectionKey, which should be easily retrieved when you call SelectionKey.attachment(), even if we are now handling a different event (retrieved during OP_READ versus put into the map during OP_ACCEPT).

The problem is that it doesn't work. When I retrieve the attachment, it is always null. And if I set up the attachment via attach() and then immediately call attachment(), it does work. Somehow between different events, it loses its association.

I'm sorry, my code is a bit long to post here, but if you look at the comments in this thread: link text ...You will see that some others have basically come to the same conclusion: that attach() and attachment() don't work, and never have.

Is there a trick to get it to work, or am I stuck with the evil overhead necessary of manually doing a lookup in a map EVERY TIME there is a new read event to handle?

Finally, is there a way to "wrap" SelectionKey in a new subclass that will properly handle attach() and attachment()?

Thanks!

like image 996
DivideByHero Avatar asked Sep 24 '26 10:09

DivideByHero


2 Answers

I have successfully attached objects to SelectionKeys without any problems, but only from the same event. For example the first time I get an OP_READ, I attach an object to the SelectionKey and on subsequent reads I retrieve it, and it works fine. Maybe OP_ACCEPT and OP_READ handle different keys because they're different events, but I think the SelectionKey should be the same for the same connection... however if you make different connections even from the same IP you will get different SelectionKeys.

UPDATE: I just checked my code and there is something very important: I didn't call attach() at all; I used the SelectableChannel.register(Selector sel, int ops, Object att) method. If you do that, subsequent calls to attachment() on the SelectionKey will work.

like image 65
Chochos Avatar answered Sep 27 '26 19:09

Chochos


There is no CR in your linked page, and I can't see anything in the Java Bug Database. However, attach/attachment is very simple code (although slightly more complicated after my bug. My guess is that you are getting a different SelectionKey, so trying to wrap it would be pointless.

like image 32
Tom Hawtin - tackline Avatar answered Sep 27 '26 19:09

Tom Hawtin - tackline