Connection.join
Douglas Surber
douglas.surber at oracle.com
Thu Jan 25 16:34:52 UTC 2018
Another alternative would be to specify that close block until the Connection is actually closed.
@Override
public default void close() {
CompletionStage<Void> future = this.closeOperation()
.submit()
.getCompletionStage();
this.releaseProhibitingMoreMembers();
future.toCompletableFuture().join(); // wait for the close Operation to complete
}
This does the right thing in many cases, maybe even the most common case, but it also likely to be surprising. This could be conditioned on a ConnectionProperty. No matter what the default is I think the behavior would be surprising to some users.
Note: This code pattern isn’t a general solution as it is incompatible with try with resources. That is user code can’t get access to the closeOperation Submission when using try with resources so this has to be built in as above.
The advantage to Connection.join is that it is very visible to the user. That’s a corollary to the principle of least surprise. Heavy operations need to be syntactically heavy. Sneaking in blocking behavior in an invisible method call, the implicit call to close made by try with resources, is likely to be surprising whereas a completely separate method call is much more likely to catch the user’s attention.
Douglas
> On Jan 25, 2018, at 7:08 AM, Douglas Surber <DOUGLAS.SURBER at oracle.com> wrote:
>
> I’ve added a new method to Connection. I’m not sure it is the right way to address the issue, though.
>
> /**
> * Wait for all member Operations of this Connection to complete.
> *
> * ISSUE: Use this method or require implementations to have some mechanism
> * to keep the JVM from exiting before all member Operations complete? App could
> * call abort if it wants to quit. That seems less surprising, but join is
> * easier to implement.
> *
> * @throws IllegalStateException if this Connection has not been submitted.
> * @return the value of the Connection
> */
> public Object join();
>
> An implementation uses background threads to do work. Those are most likely daemon threads. There needs to be a way to insure that those threads complete before the JVM exits. One way would be to require the implementation take responsibility for this. The alternative is to make the user responsible, ie the join() method above. If the implementation is responsible then the user can force the implementation to finish by Connection.abort. The Principle of Least Surprise suggests making the implementation responsible.
>
> On the other hand I haven’t thought of a good way for an implementation to be responsible. The implementation could register a shutdownHook that waits for all pending Operations to complete. Insuring that an implementation unregisters the shutdownHook when appropriate adds a lot of machinery I’d prefer to avoid. Also, since the order in which shutdownHooks run is not determined, there is no reason to believe that the rest of the system is in a proper state for ADBA to continue to run.
>
> Thoughts?
>
> Douglas
More information about the jdbc-spec-discuss
mailing list