I am in the process of learning Java NIO APIs and was able to understand how things work except attachment
object.
As far as I understand, we can create channels
like socketChannels
and attach an object to them. Whenever there is an event on a given channel then we can pick it up and its attached object.
Here, I have a requirement to modify this object (add one more key and value ) and register it with another channel say upstream channel
. Think in terms of load balancer - Taking the request from frontend and passing it to upstream channel
The issue is when I am modifying the object for upstream channel
, it gets modified for socket channel
also.
To check this - I have simplified the code. Can you please let me know how attachement
works.
public class Main {
public static void main(String[] args) {
try{
Selector selector = Selector.open();
ServerSocketChannel serverSocket = ServerSocketChannel.open();
serverSocket.bind(new InetSocketAddress("localhost", 10000));
serverSocket.configureBlocking(false);
HashMap<String, Object> attr = new HashMap<>();
attr.put("channel_type","server");
attr.put("back_connection", "");
SelectionKey selectionKey = serverSocket.register(selector, SelectionKey.OP_ACCEPT);
selectionKey.attach(attr); ----> 1 . I attach a object
while(true){
selector.selectNow();
Set<SelectionKey> selectionKeySet = selector.selectedKeys();
Iterator<SelectionKey> iter = selectionKeySet.iterator();
while(iter.hasNext()){
selectionKey = iter.next();
attr = (HashMap)selectionKey.attachment(); ------> 3. Get the attachment object again from selectionKey
System.out.println(selectionKey.channel());
String channelType = (String)attr.get("channel_type");
System.out.println( "Key is " + attr); -----> 4. It has random_value key is present in attr
if(selectionKey.isAcceptable() && channelType.equals("server")){
System.out.println("Server Connection is connected");
UUID uuid = UUID.randomUUID();
attr.put("random_value", uuid.toString()); ---> 2. Here I have modified the attr object
}
iter.remove();
}
}
}
catch(Exception e){
System.out.println("Exception has occured in socket " + e);
}
}
My question is how come, when I added a random_value
key in the hashmap, the attachment object for serverSocket
changes automatically.
As per my understanding, it should be changing only when I am attaching the modified object again with the selectionKey of the channel.