com.zeroc.IceInternal.InvocationFutureI Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ice Show documentation
Show all versions of ice Show documentation
Ice is a comprehensive RPC framework that helps you build distributed applications with minimal effort using familiar object-oriented idioms
//
// Copyright (c) ZeroC, Inc. All rights reserved.
//
package com.zeroc.IceInternal;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.BiConsumer;
import com.zeroc.Ice.Communicator;
import com.zeroc.Ice.CommunicatorDestroyedException;
import com.zeroc.Ice.Connection;
public abstract class InvocationFutureI extends com.zeroc.Ice.InvocationFuture
{
@Override
public boolean cancel()
{
return cancel(false);
}
@Override
public boolean cancel(boolean mayInterruptIfRunning)
{
//
// Call super.cancel(boolean) first. This sets the result of the future.
// Calling cancel(LocalException) also eventually attempts to complete the future
// (exceptionally), but this result is ignored.
//
boolean r = super.cancel(mayInterruptIfRunning);
cancel(new com.zeroc.Ice.InvocationCanceledException());
return r;
}
@Override
public Communicator getCommunicator()
{
return _communicator;
}
@Override
public com.zeroc.Ice.Connection getConnection()
{
return null;
}
@Override
public com.zeroc.Ice.ObjectPrx getProxy()
{
return null;
}
@Override
public final String getOperation()
{
return _operation;
}
@Override
public final void waitForCompleted()
{
if(Thread.interrupted())
{
throw new com.zeroc.Ice.OperationInterruptedException();
}
try
{
join();
}
catch(Exception ex)
{
}
}
@Override
public final boolean isSent()
{
synchronized(this)
{
return (_state & StateSent) > 0;
}
}
@Override
synchronized public final void waitForSent()
{
if(Thread.interrupted())
{
throw new com.zeroc.Ice.OperationInterruptedException();
}
while((_state & StateSent) == 0 && _exception == null)
{
try
{
this.wait();
}
catch(InterruptedException ex)
{
throw new com.zeroc.Ice.OperationInterruptedException();
}
}
}
@Override
public final boolean sentSynchronously()
{
return _sentSynchronously; // No lock needed, immutable
}
@Override
synchronized public final CompletableFuture whenSent(BiConsumer action)
{
if(_sentFuture == null)
{
_sentFuture = new CompletableFuture<>();
}
CompletableFuture r = _sentFuture.whenComplete(action);
//
// Check if the request has already been sent.
//
if(((_state & StateSent) > 0 || _exception != null) && !_sentFuture.isDone())
{
if(_exception != null)
{
_sentFuture.completeExceptionally(_exception);
}
else
{
_sentFuture.complete(_sentSynchronously);
}
}
return r;
}
@Override
synchronized public final CompletableFuture whenSentAsync(BiConsumer action)
{
return whenSentAsync(action, null);
}
@Override
synchronized public final CompletableFuture whenSentAsync(BiConsumer action,
Executor executor)
{
if(_sentFuture == null)
{
_sentFuture = new CompletableFuture<>();
}
CompletableFuture r;
if(executor == null)
{
r = _sentFuture.whenCompleteAsync(action);
}
else
{
r = _sentFuture.whenCompleteAsync(action, executor);
}
//
// Check if the request has already been sent.
//
if(((_state & StateSent) > 0 || _exception != null) && !_sentFuture.isDone())
{
if(_exception != null)
{
_sentFuture.completeExceptionally(_exception);
}
else
{
_sentFuture.complete(_sentSynchronously);
}
}
return r;
}
public final void invokeSent()
{
try
{
synchronized(this)
{
if(_sentFuture != null && !_sentFuture.isDone())
{
_sentFuture.complete(_sentSynchronously);
}
}
if(_doneInSent)
{
markCompleted();
}
}
catch(java.lang.RuntimeException ex)
{
warning(ex);
}
catch(java.lang.Error exc)
{
error(exc);
if(!(exc instanceof java.lang.AssertionError || exc instanceof java.lang.OutOfMemoryError))
{
throw exc;
}
}
if(_observer != null)
{
com.zeroc.Ice.ObjectPrx proxy = getProxy();
if(proxy == null || !proxy.ice_isTwoway())
{
_observer.detach();
_observer = null;
}
}
}
abstract protected void markCompleted();
public final void invokeCompleted()
{
try
{
if(_exception != null)
{
synchronized(this)
{
if(_sentFuture != null && !_sentFuture.isDone())
{
_sentFuture.completeExceptionally(_exception);
}
}
completeExceptionally(_exception);
}
else
{
markCompleted();
}
}
catch(RuntimeException ex)
{
warning(ex);
}
catch(AssertionError exc)
{
error(exc);
}
catch(OutOfMemoryError exc)
{
error(exc);
}
if(_observer != null)
{
_observer.detach();
_observer = null;
}
}
public final void invokeCompletedAsync()
{
//
// CommunicatorDestroyedException is the only exception that can propagate directly from this method.
//
_instance.clientThreadPool().dispatch(
new DispatchWorkItem(_cachedConnection)
{
@Override
public void run()
{
invokeCompleted();
}
});
}
synchronized public void cancelable(final CancellationHandler handler)
{
if(_cancellationException != null)
{
try
{
throw _cancellationException;
}
finally
{
_cancellationException = null;
}
}
_cancellationHandler = handler;
}
protected InvocationFutureI(Communicator communicator, Instance instance, String op)
{
_communicator = communicator;
_instance = instance;
_operation = op;
_state = 0;
_sentSynchronously = false;
_doneInSent = false;
_synchronous = false;
_exception = null;
}
protected void cacheMessageBuffers()
{
}
protected boolean sent(boolean done)
{
synchronized(this)
{
assert(_exception == null);
boolean alreadySent = (_state & StateSent) != 0;
_state |= StateSent;
if(done)
{
_state |= StateDone | StateOK;
_cancellationHandler = null;
_doneInSent = true;
//
// For oneway requests after the data has been sent
// the buffers can be reused unless this is a
// collocated invocation. For collocated invocations
// the buffer won't be reused because it has already
// been marked as cached in invokeCollocated.
//
cacheMessageBuffers();
}
boolean invoke = (!alreadySent && _sentFuture != null || done) && !_synchronous;
if(!invoke && done && _observer != null)
{
_observer.detach();
_observer = null;
};
if(!invoke && done)
{
markCompleted();
return false;
}
else
{
this.notifyAll();
return invoke;
}
}
}
protected boolean finished(boolean ok, boolean invoke)
{
synchronized(this)
{
_state |= StateDone;
if(ok)
{
_state |= StateOK;
}
_cancellationHandler = null;
invoke &= !_synchronous;
if(!invoke && _observer != null)
{
_observer.detach();
_observer = null;
}
if(!invoke)
{
if(_exception != null)
{
completeExceptionally(_exception);
}
else
{
markCompleted();
}
return false;
}
else
{
this.notifyAll();
return invoke;
}
}
}
protected boolean finished(com.zeroc.Ice.Exception ex)
{
synchronized(this)
{
_state |= StateDone;
_exception = ex;
_cancellationHandler = null;
if(_observer != null)
{
_observer.failed(ex.ice_id());
}
boolean invoke = !_synchronous;
if(!invoke && _observer != null)
{
_observer.detach();
_observer = null;
}
if(!invoke)
{
if(_exception != null)
{
completeExceptionally(_exception);
}
else
{
markCompleted();
}
return false;
}
else
{
this.notifyAll();
return invoke;
}
}
}
public final void invokeSentAsync()
{
//
// This is called when it's not safe to call the sent callback
// synchronously from this thread. Instead the future is completed
// asynchronously from a client in the client thread pool.
//
dispatch(() -> invokeSent());
}
protected void cancel(com.zeroc.Ice.LocalException ex)
{
CancellationHandler handler;
synchronized(this)
{
if(_cancellationHandler == null)
{
_cancellationException = ex;
return;
}
handler = _cancellationHandler;
}
handler.asyncRequestCanceled((OutgoingAsyncBase)this, ex);
}
protected com.zeroc.Ice.Instrumentation.InvocationObserver getObserver()
{
return _observer;
}
protected void dispatch(final Runnable runnable)
{
try
{
_instance.clientThreadPool().dispatch(
new DispatchWorkItem(_cachedConnection)
{
@Override
public void run()
{
runnable.run();
}
});
}
catch(CommunicatorDestroyedException ex)
{
}
}
private void warning(RuntimeException ex)
{
if(_instance.initializationData().properties.getPropertyAsIntWithDefault("Ice.Warn.AMICallback", 1) > 0)
{
String s = "exception raised by AMI callback:\n" + Ex.toString(ex);
_instance.initializationData().logger.warning(s);
}
}
private void error(Error error)
{
String s = "error raised by AMI callback:\n" + Ex.toString(error);
_instance.initializationData().logger.error(s);
}
protected final Instance _instance;
protected com.zeroc.Ice.Instrumentation.InvocationObserver _observer;
protected Connection _cachedConnection;
protected boolean _sentSynchronously;
protected boolean _doneInSent;
protected boolean _synchronous; // True if this AMI request is being used for a generated synchronous invocation.
protected CompletableFuture _sentFuture;
protected final Communicator _communicator;
protected final String _operation;
protected com.zeroc.Ice.Exception _exception;
private CancellationHandler _cancellationHandler;
private com.zeroc.Ice.LocalException _cancellationException;
protected static final byte StateOK = 0x1;
protected static final byte StateDone = 0x2;
protected static final byte StateSent = 0x4;
protected static final byte StateCachedBuffers = 0x08;
protected byte _state;
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy