final UniqueId viewId = storeViewDefinition(executionContext, target.getUniqueId(), viewEvaluation.getViewDefinition());
final ViewProcessor viewProcessor = OpenGammaExecutionContext.getViewProcessor(executionContext);
if (viewProcessor == null) {
throw new IllegalStateException("Execution context does not contain a " + OpenGammaExecutionContext.VIEW_PROCESSOR_NAME);
}
final ViewClient viewClient = viewProcessor.createViewClient(viewEvaluation.getViewDefinition().getMarketDataUser());
final UniqueId viewClientId = viewClient.getUniqueId();
s_logger.info("Created view client {}, connecting to {}", viewClientId, viewId);
viewClient.attachToViewProcess(viewId,
ExecutionOptions.of(viewEvaluation.getExecutionSequence().createSequence(executionContext), getDefaultCycleOptions(executionContext), getViewExecutionFlags(desiredValues)), true);
final TResultBuilder resultBuilder = createResultBuilder(viewEvaluation, desiredValues);
final AsynchronousOperation<Set<ComputedValue>> async = AsynchronousOperation.createSet();
final AtomicReference<ResultCallback<Set<ComputedValue>>> asyncResult = new AtomicReference<ResultCallback<Set<ComputedValue>>>(async.getCallback());
viewClient.setResultListener(new ViewResultListener() {
private void reportException(final RuntimeException e) {
final ResultCallback<?> callback = asyncResult.getAndSet(null);
if (callback != null) {
try {
callback.setException(e);
} finally {
s_logger.info("Shutting down view client {}", viewClientId);
viewClient.shutdown();
}
} else {
s_logger.warn("Callback already made before exception for {}", viewClientId);
}
}
private void reportResult(final Set<ComputedValue> values) {
final ResultCallback<Set<ComputedValue>> callback = asyncResult.getAndSet(null);
if (callback != null) {
try {
callback.setResult(values);
} finally {
s_logger.info("Shutting down view client {}", viewClientId);
viewClient.shutdown();
}
} else {
s_logger.warn("Callback already made before results for {}", viewClientId);
}
}
@Override
public UserPrincipal getUser() {
return viewEvaluation.getViewDefinition().getMarketDataUser();
}
@Override
public void viewDefinitionCompiled(final CompiledViewDefinition compiledViewDefinition, final boolean hasMarketDataPermissions) {
s_logger.debug("View definition compiled for {}", viewClientId);
try {
store(compiledViewDefinition, resultBuilder);
} catch (final RuntimeException e) {
s_logger.error("Caught exception during compilation completed callback", e);
reportException(e);
}
}
@Override
public void viewDefinitionCompilationFailed(final Instant valuationTime, final Exception exception) {
s_logger.error("View compilation failure for {} - {}", viewClientId, exception);
reportException(new OpenGammaRuntimeException("View definition compilation failed for " + valuationTime, exception));
}
@Override
public void cycleStarted(final ViewCycleMetadata cycleMetadata) {
// This is good. Don't need to do anything.
s_logger.debug("Cycle started for {}", viewClientId);
}
@Override
public void cycleFragmentCompleted(final ViewComputationResultModel fullFragment, final ViewDeltaResultModel deltaFragment) {
// This shouldn't happen. We've asked for full results only
s_logger.error("Cycle fragment completed for {}", viewClientId);
reportException(new OpenGammaRuntimeException("Assertion error"));
assert false;
}
@Override
public void cycleCompleted(final ViewComputationResultModel fullResult, final ViewDeltaResultModel deltaResult) {
s_logger.debug("Cycle completed for {}", viewClientId);
try {
store(fullResult, resultBuilder);
} catch (final RuntimeException e) {
s_logger.error("Caught exception during cycle completed callback", e);
reportException(e);
}
}
@Override
public void cycleExecutionFailed(final ViewCycleExecutionOptions executionOptions, final Exception exception) {
s_logger.error("Cycle execution failed for {}", viewClientId);
reportException(new OpenGammaRuntimeException("View cycle execution failed for " + executionOptions, exception));
}
@Override
public void processCompleted() {
s_logger.info("View process completed for {}", viewClientId);
try {
Set<ComputedValue> results = buildResults(target, resultBuilder);
reportResult(results);
} catch (final RuntimeException e) {
s_logger.error("Caught exception during process completed callback", e);
reportException(e);
}
}
@Override
public void processTerminated(final boolean executionInterrupted) {
// Normally we would have expected one of the other notifications, so if the callback exists we report an error
final ResultCallback<?> callback = asyncResult.getAndSet(null);
if (callback != null) {
s_logger.error("View process terminated for {}", viewClientId);
reportException(new OpenGammaRuntimeException(executionInterrupted ? "Execution interrupted" : "View process terminated"));
} else {
s_logger.debug("View process terminated for {}", viewClientId);
}
}
@Override
public void clientShutdown(final Exception e) {
// Normally we would have expected one of the other notifications or this in response to us calling "shutdown", so if the callback exists we report an error
final ResultCallback<?> callback = asyncResult.getAndSet(null);
if (callback != null) {
s_logger.error("View client shutdown for {}", viewClientId);
reportException(new OpenGammaRuntimeException("View client shutdown", e));
} else {
s_logger.debug("View client shutdown for {}", viewClientId);
}
}
});
viewClient.triggerCycle();
return async.getResult();
}