hg: nio/nio/jdk: First installation of potential updates for M4
Alexander Libman
libman at terabit.com.au
Sun May 17 19:39:15 PDT 2009
>
> No, it shouldn't interfere with other I/O operations. For example on a
> channel to a stream socket then you might cancel a read and this should
> not interfere with a concurrent write. In this case the cancel may not
> be able to guarantee that bytes have not been transferred so this will
> prevent further reads on the channel (but it should not impact writing).
>
Very clear. May be couple lines from above paragraph would be nice to see
in javadoc.
> > What should we do if mayInterruptIfRunninng = false and there
> is no way to
> > cancel/fail/complete immediately?
> > Seems, the only one alternative is to block in cancel().
> >
> No, you should simply update its state to cancelled, release any
> waiters, and return *true*. Everything falls into place after that. That
> is, isDone and isCancelled will return true and any subsequent calls to
> get will throw CancellationException.
I was thinking about such solution earlier. It will work fine only with one
condition:
user must discard buffers used in cancelled operation.
I wanted avoid discarding buffers and provide the following guarantee at
least in filters:
If a completion is delivered (exception/result or the moment of invocation
the completion handler), then
the developer can reuse buffers for the finished operation.
Why I am worried about reusing buffers?
Assume we have TCP/IP server serving several thousand connections (HTTP is
a good example).
If half of connections go down (clients can misbehave, network problems,
etc ), with must discard thousand buffers.
Big job for garbage collector and it takes some time.. And at the same time
a lot of new connections come in and we should allocate buffers for them.
Do we have chance to run out of memory?
Having buffers reusable after any completion (normal, failure or
cancellation), we can resolve problem of thousand connections by pooling
buffers.
If discarding buffers is efficient as pooling in modern VM, I would be happy
and cancel my question.
If discarding buffers is required only for cancelled operations and not for
all other failures, I would be also OK.
Because scalable servers probably will be written using Completion
Handlers, where there are no visible Futures<> and cancel() out of the
question.
Sorry, my C++ experience developed paranoid habit to take care about
releasing resources :)
I remember in 2003 we run out of Oracle DB connections and system file
handles in Java VM because all connections had gone to GC.
Disaster happened because all those connections contained native handles.
I assume that JavaVM 1.6 and 1.7 is much better than 1.3 and may be now it
is not a problem.
My concern is only that buffers are significant resources and we can come
across the similar issue.
> >
> > boolean cancel(boolean mayInterruptIfRunning)
> >
> > Attempts to cancel execution of this task. This attempt will fail :
> > a)if the task has already completed (OK)
> > b)has already been cancelled (OK)
> > c)or could not be cancelled for some other reason (??)
> >
> > I would like to use the third option ("for some other reason",i.e. not
> > cancellable) and return false.
> > But " After this method returns, subsequent calls to isDone()
> will always
> > return true".
> > This force me to wait in cancel () if operation is not cancellable "for
> > some other reason".
> >
> I tripped up on this too and had to be rescued by the jsr166 folks.
> There really isn't a third option and you have to return true if the I/O
> has not completed or has not been cancelled.
>
Would be nice to remove "for some other reason" from doc.
My case is typical example of reading and thinking about "some other
reason",
that I missed that "isDone()" must be true after cancel :)
> > :
> >
> > Last question: is Future.get () idempotent method ?
> >
> It always returns the same result as the result from the first invocation.
Good. I asked because it allows to implement non-cancellable cancel()
without discarding buffers in form
cancel (boolean mayInterruptIfRunning)
{
if (! mayInterruptIfRunning) {
try {
this.get();
}
catch (Exception e)
{}
return isCancelled(); // actually always returns false
}
....
}
Alex
More information about the nio-dev
mailing list