use of com.microsoft.identity.common.internal.result.FinalizableResultFuture in project microsoft-authentication-library-common-for-android by AzureAD.
the class CommandDispatcher method submitSilentReturningFuture.
/**
* submitSilent - Run a command using the silent thread pool, and return the future governing it.
*
* @param command
*/
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
public static FinalizableResultFuture<CommandResult> submitSilentReturningFuture(@SuppressWarnings(WarningType.rawtype_warning) @NonNull final BaseCommand command) {
final String methodName = ":submitSilent";
final CommandParameters commandParameters = command.getParameters();
final String correlationId = initializeDiagnosticContext(commandParameters.getCorrelationId(), commandParameters.getSdkType() == null ? SdkType.UNKNOWN.getProductName() : commandParameters.getSdkType().getProductName(), commandParameters.getSdkVersion());
// set correlation id on parameters as it may not already be set
commandParameters.setCorrelationId(correlationId);
logParameters(TAG + methodName, correlationId, commandParameters, command.getPublicApiId());
final Handler handler = new Handler(Looper.getMainLooper());
synchronized (mapAccessLock) {
final FinalizableResultFuture<CommandResult> finalFuture;
if (command.isEligibleForCaching()) {
FinalizableResultFuture<CommandResult> future = sExecutingCommandMap.get(command);
if (null == future) {
future = new FinalizableResultFuture<>();
final FinalizableResultFuture<CommandResult> putValue = sExecutingCommandMap.putIfAbsent(command, future);
if (null == putValue) {
// our value was inserted.
future.whenComplete(getCommandResultConsumer(command, handler));
} else {
// Our value was not inserted, grab the one that was and hang a new listener off it
putValue.whenComplete(getCommandResultConsumer(command, handler));
return putValue;
}
} else {
future.whenComplete(getCommandResultConsumer(command, handler));
return future;
}
finalFuture = future;
} else {
finalFuture = new FinalizableResultFuture<>();
finalFuture.whenComplete(getCommandResultConsumer(command, handler));
}
sSilentExecutor.execute(new Runnable() {
@Override
public void run() {
try {
// initializing again since the request is transferred to a different thread pool
initializeDiagnosticContext(correlationId, commandParameters.getSdkType() == null ? SdkType.UNKNOWN.getProductName() : commandParameters.getSdkType().getProductName(), commandParameters.getSdkVersion());
EstsTelemetry.getInstance().initTelemetryForCommand(command);
EstsTelemetry.getInstance().emitApiId(command.getPublicApiId());
CommandResult commandResult = null;
// Log operation parameters
if (command.getParameters() instanceof SilentTokenCommandParameters) {
EstsTelemetry.getInstance().emitForceRefresh(((SilentTokenCommandParameters) command.getParameters()).isForceRefresh());
}
// If nothing in cache, execute the command and cache the result
if (commandResult == null) {
commandResult = executeCommand(command);
// Disabling throttling ADO:1383033
// cacheCommandResult(command, commandResult);
Logger.info(TAG + methodName, "Completed silent request as owner for correlation id : **" + correlationId + ", with the status : " + commandResult.getStatus().getLogStatus() + " is cacheable : " + command.isEligibleForCaching());
} else {
Logger.info(TAG + methodName, "Silent command result returned from cache for correlation id : " + correlationId + " having status : " + commandResult.getStatus().getLogStatus());
// Added to keep the original correlation id intact, and to not let it mutate with the cascading requests hitting the cache.
commandResult = new CommandResult(commandResult.getStatus(), commandResult.getResult(), commandResult.getCorrelationId());
}
// TODO 1309671 : change required to stop the LocalAuthenticationResult object from mutating in cases of cached command.
// set correlation id on Local Authentication Result
setCorrelationIdOnResult(commandResult, correlationId);
Telemetry.getInstance().flush(correlationId);
EstsTelemetry.getInstance().flush(command, commandResult);
finalFuture.setResult(commandResult);
} catch (final Throwable t) {
Logger.info(TAG + methodName, "Request encountered an exception with correlation id : **" + correlationId);
finalFuture.setException(new ExecutionException(t));
} finally {
synchronized (mapAccessLock) {
if (command.isEligibleForCaching()) {
final FinalizableResultFuture mapFuture = sExecutingCommandMap.remove(command);
if (mapFuture == null) {
// If this has happened, the command that we started with has mutated. We will
// examine every entry in the map, find the one with the same object identity
// and remove it.
// ADO:TODO:1153495 - Rekey this map with stable string keys.
Logger.error(TAG, "The command in the map has mutated " + command.getClass().getCanonicalName() + " the calling application was " + command.getParameters().getApplicationName(), null);
cleanMap(command);
}
}
finalFuture.setCleanedUp();
}
DiagnosticContext.clear();
}
}
});
return finalFuture;
}
}
Aggregations