Use progress + total instead of delta
.. because there is sometimes a task whose total is only a rough estimation
This commit is contained in:
parent
e69033a4c3
commit
7ee571968c
@ -43,8 +43,8 @@ public abstract class AbstractEventExecutor extends AbstractExecutorService impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <V> ProgressivePromise<V> newProgressivePromise(long total) {
|
public <V> ProgressivePromise<V> newProgressivePromise() {
|
||||||
return new DefaultProgressivePromise<V>(this, total);
|
return new DefaultProgressivePromise<V>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -18,70 +18,42 @@ package io.netty.util.concurrent;
|
|||||||
|
|
||||||
public class DefaultProgressivePromise<V> extends DefaultPromise<V> implements ProgressivePromise<V> {
|
public class DefaultProgressivePromise<V> extends DefaultPromise<V> implements ProgressivePromise<V> {
|
||||||
|
|
||||||
private final long total;
|
|
||||||
private volatile long progress;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance.
|
* Creates a new instance.
|
||||||
*
|
*
|
||||||
* It is preferable to use {@link EventExecutor#newProgressivePromise(long)} to create a new progressive promise
|
* It is preferable to use {@link EventExecutor#newProgressivePromise()} to create a new progressive promise
|
||||||
*
|
*
|
||||||
* @param executor
|
* @param executor
|
||||||
* the {@link EventExecutor} which is used to notify the promise when it progresses or it is complete
|
* the {@link EventExecutor} which is used to notify the promise when it progresses or it is complete
|
||||||
*/
|
*/
|
||||||
public DefaultProgressivePromise(EventExecutor executor, long total) {
|
public DefaultProgressivePromise(EventExecutor executor) {
|
||||||
super(executor);
|
super(executor);
|
||||||
validateTotal(total);
|
|
||||||
this.total = total;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected DefaultProgressivePromise(long total) {
|
protected DefaultProgressivePromise() { /* only for subclasses */ }
|
||||||
/* only for subclasses */
|
|
||||||
validateTotal(total);
|
|
||||||
this.total = total;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void validateTotal(long total) {
|
|
||||||
if (total < 0) {
|
|
||||||
throw new IllegalArgumentException("total: " + total + " (expected: >= 0)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long progress() {
|
public ProgressivePromise<V> setProgress(long progress, long total) {
|
||||||
return progress;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long total() {
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ProgressivePromise<V> setProgress(long progress) {
|
|
||||||
if (progress < 0 || progress > total) {
|
if (progress < 0 || progress > total) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"progress: " + progress + " (expected: 0 <= progress <= " + total + ')');
|
"progress: " + progress + " (expected: 0 <= progress <= total (" + total + "))");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isDone()) {
|
if (isDone()) {
|
||||||
throw new IllegalStateException("complete already");
|
throw new IllegalStateException("complete already");
|
||||||
}
|
}
|
||||||
|
|
||||||
long oldProgress = this.progress;
|
notifyProgressiveListeners(progress, total);
|
||||||
this.progress = progress;
|
|
||||||
notifyProgressiveListeners(progress - oldProgress);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean tryProgress(long progress) {
|
public boolean tryProgress(long progress, long total) {
|
||||||
if (progress < 0 || progress > total || isDone()) {
|
if (progress < 0 || progress > total || isDone()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.progress = progress;
|
notifyProgressiveListeners(progress, total);
|
||||||
notifyProgressiveListeners(progress);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -605,7 +605,7 @@ public class DefaultPromise<V> extends AbstractFuture<V> implements Promise<V> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
void notifyProgressiveListeners(final long delta) {
|
void notifyProgressiveListeners(final long progress, final long total) {
|
||||||
final Object listeners = progressiveListeners();
|
final Object listeners = progressiveListeners();
|
||||||
if (listeners == null) {
|
if (listeners == null) {
|
||||||
return;
|
return;
|
||||||
@ -616,10 +616,11 @@ public class DefaultPromise<V> extends AbstractFuture<V> implements Promise<V> {
|
|||||||
EventExecutor executor = executor();
|
EventExecutor executor = executor();
|
||||||
if (executor.inEventLoop()) {
|
if (executor.inEventLoop()) {
|
||||||
if (listeners instanceof GenericProgressiveFutureListener[]) {
|
if (listeners instanceof GenericProgressiveFutureListener[]) {
|
||||||
notifyProgressiveListeners0(self, (GenericProgressiveFutureListener<?>[]) listeners, delta);
|
notifyProgressiveListeners0(
|
||||||
|
self, (GenericProgressiveFutureListener<?>[]) listeners, progress, total);
|
||||||
} else {
|
} else {
|
||||||
notifyProgressiveListener0(
|
notifyProgressiveListener0(
|
||||||
self, (GenericProgressiveFutureListener<ProgressiveFuture<V>>) listeners, delta);
|
self, (GenericProgressiveFutureListener<ProgressiveFuture<V>>) listeners, progress, total);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
@ -629,7 +630,7 @@ public class DefaultPromise<V> extends AbstractFuture<V> implements Promise<V> {
|
|||||||
executor.execute(new Runnable() {
|
executor.execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
notifyProgressiveListeners0(self, array, delta);
|
notifyProgressiveListeners0(self, array, progress, total);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -638,7 +639,7 @@ public class DefaultPromise<V> extends AbstractFuture<V> implements Promise<V> {
|
|||||||
executor.execute(new Runnable() {
|
executor.execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
notifyProgressiveListener0(self, l, delta);
|
notifyProgressiveListener0(self, l, progress, total);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -649,20 +650,20 @@ public class DefaultPromise<V> extends AbstractFuture<V> implements Promise<V> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void notifyProgressiveListeners0(
|
private static void notifyProgressiveListeners0(
|
||||||
ProgressiveFuture<?> future, GenericProgressiveFutureListener<?>[] listeners, long delta) {
|
ProgressiveFuture<?> future, GenericProgressiveFutureListener<?>[] listeners, long progress, long total) {
|
||||||
for (GenericProgressiveFutureListener<?> l: listeners) {
|
for (GenericProgressiveFutureListener<?> l: listeners) {
|
||||||
if (l == null) {
|
if (l == null) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
notifyProgressiveListener0(future, l, delta);
|
notifyProgressiveListener0(future, l, progress, total);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
private static void notifyProgressiveListener0(
|
private static void notifyProgressiveListener0(
|
||||||
ProgressiveFuture future, GenericProgressiveFutureListener l, long delta) {
|
ProgressiveFuture future, GenericProgressiveFutureListener l, long progress, long total) {
|
||||||
try {
|
try {
|
||||||
l.operationProgressed(future, delta);
|
l.operationProgressed(future, progress, total);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
if (logger.isWarnEnabled()) {
|
if (logger.isWarnEnabled()) {
|
||||||
logger.warn("An exception was thrown by " + l.getClass().getName() + ".operationProgressed()", t);
|
logger.warn("An exception was thrown by " + l.getClass().getName() + ".operationProgressed()", t);
|
||||||
|
@ -54,7 +54,7 @@ public interface EventExecutor extends EventExecutorGroup {
|
|||||||
/**
|
/**
|
||||||
* Create a new {@link ProgressivePromise}.
|
* Create a new {@link ProgressivePromise}.
|
||||||
*/
|
*/
|
||||||
<V> ProgressivePromise<V> newProgressivePromise(long total);
|
<V> ProgressivePromise<V> newProgressivePromise();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@link Future} which is marked as successes already. So {@link Future#isSuccess()}
|
* Create a new {@link Future} which is marked as successes already. So {@link Future#isSuccess()}
|
||||||
|
@ -17,5 +17,5 @@
|
|||||||
package io.netty.util.concurrent;
|
package io.netty.util.concurrent;
|
||||||
|
|
||||||
public interface GenericProgressiveFutureListener<F extends ProgressiveFuture<?>> extends GenericFutureListener<F> {
|
public interface GenericProgressiveFutureListener<F extends ProgressiveFuture<?>> extends GenericFutureListener<F> {
|
||||||
void operationProgressed(F future, long delta) throws Exception;
|
void operationProgressed(F future, long progress, long total) throws Exception;
|
||||||
}
|
}
|
||||||
|
@ -21,16 +21,6 @@ package io.netty.util.concurrent;
|
|||||||
*/
|
*/
|
||||||
public interface ProgressiveFuture<V> extends Future<V> {
|
public interface ProgressiveFuture<V> extends Future<V> {
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the current progress of the operation as a positive long integer.
|
|
||||||
*/
|
|
||||||
long progress();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the maximum progress of the operation that signifies the end of operation.
|
|
||||||
*/
|
|
||||||
long total();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ProgressiveFuture<V> addListener(GenericFutureListener<? extends Future<V>> listener);
|
ProgressiveFuture<V> addListener(GenericFutureListener<? extends Future<V>> listener);
|
||||||
|
|
||||||
|
@ -24,14 +24,14 @@ public interface ProgressivePromise<V> extends Promise<V>, ProgressiveFuture<V>
|
|||||||
* Sets the current progress of the operation and notifies the listeners that implement
|
* Sets the current progress of the operation and notifies the listeners that implement
|
||||||
* {@link GenericProgressiveFutureListener}.
|
* {@link GenericProgressiveFutureListener}.
|
||||||
*/
|
*/
|
||||||
ProgressivePromise<V> setProgress(long progress);
|
ProgressivePromise<V> setProgress(long progress, long total);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to set the current progress of the operation and notifies the listeners that implement
|
* Tries to set the current progress of the operation and notifies the listeners that implement
|
||||||
* {@link GenericProgressiveFutureListener}. If the operation is already complete or the progress is out of range,
|
* {@link GenericProgressiveFutureListener}. If the operation is already complete or the progress is out of range,
|
||||||
* this method does nothing but returning {@code false}.
|
* this method does nothing but returning {@code false}.
|
||||||
*/
|
*/
|
||||||
boolean tryProgress(long progress);
|
boolean tryProgress(long progress, long total);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ProgressivePromise<V> setSuccess(V result);
|
ProgressivePromise<V> setSuccess(V result);
|
||||||
|
@ -106,15 +106,15 @@ public class FileServer {
|
|||||||
}
|
}
|
||||||
ctx.write(file + " " + file.length() + '\n');
|
ctx.write(file + " " + file.length() + '\n');
|
||||||
FileRegion region = new DefaultFileRegion(new FileInputStream(file).getChannel(), 0, file.length());
|
FileRegion region = new DefaultFileRegion(new FileInputStream(file).getChannel(), 0, file.length());
|
||||||
ChannelProgressivePromise promise = ctx.newProgressivePromise(region.count());
|
ChannelProgressivePromise promise = ctx.newProgressivePromise();
|
||||||
promise.addListener(new ChannelProgressiveFutureListener() {
|
promise.addListener(new ChannelProgressiveFutureListener() {
|
||||||
@Override
|
@Override
|
||||||
public void operationProgressed(ChannelProgressiveFuture f, long delta) throws Exception {
|
public void operationProgressed(ChannelProgressiveFuture f, long progress, long total) {
|
||||||
System.err.println("progress: " + f.progress() + " / " + f.total() + " (+" + delta + ')');
|
System.err.println("progress: " + progress + " / " + total);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void operationComplete(ChannelProgressiveFuture future) throws Exception {
|
public void operationComplete(ChannelProgressiveFuture future) {
|
||||||
System.err.println("file transfer complete");
|
System.err.println("file transfer complete");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -307,8 +307,8 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChannelProgressivePromise newProgressivePromise(long total) {
|
public ChannelProgressivePromise newProgressivePromise() {
|
||||||
return new DefaultChannelProgressivePromise(this, total);
|
return new DefaultChannelProgressivePromise(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -58,5 +58,5 @@ public interface ChannelProgressivePromise extends ProgressivePromise<Void>, Cha
|
|||||||
ChannelProgressivePromise setFailure(Throwable cause);
|
ChannelProgressivePromise setFailure(Throwable cause);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ChannelProgressivePromise setProgress(long progress);
|
ChannelProgressivePromise setProgress(long progress, long total);
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ interface ChannelPropertyAccess {
|
|||||||
/**
|
/**
|
||||||
* Return an new {@link ChannelProgressivePromise}
|
* Return an new {@link ChannelProgressivePromise}
|
||||||
*/
|
*/
|
||||||
ChannelProgressivePromise newProgressivePromise(long total);
|
ChannelProgressivePromise newProgressivePromise();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@link ChannelFuture} which is marked as successes already. So {@link ChannelFuture#isSuccess()}
|
* Create a new {@link ChannelFuture} which is marked as successes already. So {@link ChannelFuture#isSuccess()}
|
||||||
|
@ -1558,8 +1558,8 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChannelProgressivePromise newProgressivePromise(long total) {
|
public ChannelProgressivePromise newProgressivePromise() {
|
||||||
return new DefaultChannelProgressivePromise(channel(), executor(), total);
|
return new DefaultChannelProgressivePromise(channel(), executor());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -23,7 +23,7 @@ import io.netty.util.concurrent.GenericFutureListener;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The default {@link ChannelProgressivePromise} implementation. It is recommended to use
|
* The default {@link ChannelProgressivePromise} implementation. It is recommended to use
|
||||||
* {@link Channel#newProgressivePromise(long)} to create a new {@link ChannelProgressivePromise} rather than calling the
|
* {@link Channel#newProgressivePromise()} to create a new {@link ChannelProgressivePromise} rather than calling the
|
||||||
* constructor explicitly.
|
* constructor explicitly.
|
||||||
*/
|
*/
|
||||||
public class DefaultChannelProgressivePromise
|
public class DefaultChannelProgressivePromise
|
||||||
@ -37,8 +37,7 @@ public class DefaultChannelProgressivePromise
|
|||||||
* @param channel
|
* @param channel
|
||||||
* the {@link Channel} associated with this future
|
* the {@link Channel} associated with this future
|
||||||
*/
|
*/
|
||||||
public DefaultChannelProgressivePromise(Channel channel, long total) {
|
public DefaultChannelProgressivePromise(Channel channel) {
|
||||||
super(total);
|
|
||||||
this.channel = channel;
|
this.channel = channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,8 +47,8 @@ public class DefaultChannelProgressivePromise
|
|||||||
* @param channel
|
* @param channel
|
||||||
* the {@link Channel} associated with this future
|
* the {@link Channel} associated with this future
|
||||||
*/
|
*/
|
||||||
public DefaultChannelProgressivePromise(Channel channel, EventExecutor executor, long total) {
|
public DefaultChannelProgressivePromise(Channel channel, EventExecutor executor) {
|
||||||
super(executor, total);
|
super(executor);
|
||||||
this.channel = channel;
|
this.channel = channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,8 +90,8 @@ public class DefaultChannelProgressivePromise
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChannelProgressivePromise setProgress(long progress) {
|
public ChannelProgressivePromise setProgress(long progress, long total) {
|
||||||
super.setProgress(progress);
|
super.setProgress(progress, total);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,8 +187,7 @@ public abstract class AbstractNioByteChannel extends AbstractNioChannel {
|
|||||||
} else {
|
} else {
|
||||||
writtenBytes += localWrittenBytes;
|
writtenBytes += localWrittenBytes;
|
||||||
if (promise instanceof ChannelProgressivePromise) {
|
if (promise instanceof ChannelProgressivePromise) {
|
||||||
final ChannelProgressivePromise pp = (ChannelProgressivePromise) promise;
|
((ChannelProgressivePromise) promise).setProgress(writtenBytes, region.count());
|
||||||
pp.setProgress(pp.progress() + localWrittenBytes);
|
|
||||||
}
|
}
|
||||||
if (writtenBytes >= region.count()) {
|
if (writtenBytes >= region.count()) {
|
||||||
region.release();
|
region.release();
|
||||||
|
@ -112,8 +112,8 @@ public abstract class OioByteStreamChannel extends AbstractOioByteChannel {
|
|||||||
if (outChannel == null) {
|
if (outChannel == null) {
|
||||||
outChannel = Channels.newChannel(os);
|
outChannel = Channels.newChannel(os);
|
||||||
}
|
}
|
||||||
long written = 0;
|
|
||||||
|
|
||||||
|
long written = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
long localWritten = region.transferTo(outChannel, written);
|
long localWritten = region.transferTo(outChannel, written);
|
||||||
if (localWritten == -1) {
|
if (localWritten == -1) {
|
||||||
@ -125,7 +125,7 @@ public abstract class OioByteStreamChannel extends AbstractOioByteChannel {
|
|||||||
written += localWritten;
|
written += localWritten;
|
||||||
if (promise instanceof ChannelProgressivePromise) {
|
if (promise instanceof ChannelProgressivePromise) {
|
||||||
final ChannelProgressivePromise pp = (ChannelProgressivePromise) promise;
|
final ChannelProgressivePromise pp = (ChannelProgressivePromise) promise;
|
||||||
pp.setProgress(pp.progress() + localWritten);
|
pp.setProgress(written, region.count());
|
||||||
}
|
}
|
||||||
if (written >= region.count()) {
|
if (written >= region.count()) {
|
||||||
promise.setSuccess();
|
promise.setSuccess();
|
||||||
|
@ -564,8 +564,7 @@ public class AioSocketChannel extends AbstractAioChannel implements SocketChanne
|
|||||||
written += result;
|
written += result;
|
||||||
|
|
||||||
if (promise instanceof ChannelProgressivePromise) {
|
if (promise instanceof ChannelProgressivePromise) {
|
||||||
final ChannelProgressivePromise pp = (ChannelProgressivePromise) promise;
|
((ChannelProgressivePromise) promise).setProgress(written, region.count());
|
||||||
pp.setProgress(pp.progress() + result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (written >= region.count()) {
|
if (written >= region.count()) {
|
||||||
|
Loading…
Reference in New Issue
Block a user