java.nio.channels.MembershipKey API

David M. Lloyd david.lloyd at redhat.com
Fri Nov 28 14:16:43 PST 2008


On 11/27/2008 02:28 PM, Alan Bateman wrote:
> David M. Lloyd wrote:
>> :
>> Well, that wasn't my point.  I don't think anyone would reasonably 
>> expect a multicast membership key to outlive the channel.  My point is 
>> that, given that there's a standard resource cleanup I/O interface 
>> (Closeable), and that drop() conforms to it exactly apart from the 
>> name, why not use it?
> I appreciate this wasn't your point but your comment helped to highlight 
> that an explicit statement to that effect was missing.
> 
> I agree that implementing Closeable to work with resource clean-up 
> facilities is good (we need to retrofit Selector implement it, as you 
> pointed out a few months ago).  However, I don't see a big need for 
> classes such as FileLock, SelectionKey, and MembershipKey to implement 
> it. These are tokens rather than data sources or destinations. I would 
> expect the channel to be registered with the clean-up facility; when its 
> close method is invoked, then it releases all resources and invalidates 
> all the associated token objects.

FileLock and SelectionKey are, apart from other issues, already set in 
stone as they are part of the JDK.  I don't think these two classes have 
any bearing on MembershipKey as a new class.  Consider this simple case:

Jane User realizes that she frequently has to write code that looks like this:

SomeResource r = ...create...;
try {
     ...do stuff..
} finally {
     try {
         r.close();
     } catch (IOException e) {
         log.error("Failed to close " + r, e);
     }
}

Realizing that the finally block is boilerplate, she introduces a static 
method on a util class:

public static void safeClose(Closeable c) {
     try {
         c.close();
     } catch (IOException e) {
         log.error("Failed to close " + c, e);
     }
}

Much typing and annoyance is saved.  Everything is well and good until she 
runs across this new case:

public void addMembership(DatagramChannel ch, InetAddress group, 
NetworkInterface intf) throws IOException {
     boolean ok = false;
     MembershipKey key = ch.join(group, intf);
     try {
         ...send & receive some messages, and run some app logic, any of 
which might fail...
         ok = true;
     } finally {
         // rats.  if only I could use safeClose(), this whole thing would 
be one simple, readable line
         if (! ok) {
             try {
                 key.drop();
             } catch (IOException e) {
                 log.error("Failed to close " + key, e);
             }
         }
     }
}

Her only recourse is to add another safeClose() method:

/**
  * I repeat myself when under stress.  I repeat myself when under stress. 
  I repeat myself when under stress.
  * I repeat myself when under stress.  I repeat myself when under stress. 
  I repeat myself when under stress.
  * I repeat myself when under stress.  I repeat myself when under stress. 
  I repeat myself when under stress.
  */
public static void safeClose(MembershipKey key) {
     try {
         key.drop();
     } catch (IOException e) {
         log.error("Failed to close " + key, e);
     }
}

Minor, but annoying.  This kind of thing happens far too much in the JDK. 
Jane User already has the same method defined for selectors, ZipFiles, 
Sockets, and ServerSockets, not to mention JDBC resources, JDK logging 
handlers, MIDI stuff, etc.  Why perpetuate it to one more class?  Just 
because it ends in *Key?  The usage pattern is the same.

My final attempt,
- DML



More information about the nio-dev mailing list