private async Task RepeatGetStateAsync(int repeatMillis, CancellationTokenSource tokenSource) { while (true) { if (IsCommandInProgress) { continue; } try { // TODO(): Handle timeout and other exceptions here. StateResponse stateCheckResult = await m_coreLink.Request(new GetStateConversation(), DefaultKeepaliveTimeoutMs) .ConfigureAwait(false); // Check this again - the cancellation could have come during the request. if (!tokenSource.IsCancellationRequested) { m_stateResultAction(new KeepaliveResult(stateCheckResult)); } } catch (Exception ex) { // TODO(HonzaS): if this keeps on failing, notify the user. Log.Warn("Periodic state check failed: {message}", ex.Message); m_stateResultAction(new KeepaliveResult(KeepaliveResultTag.RequestFailed)); } try { await Task.Delay(repeatMillis, tokenSource.Token).ConfigureAwait(false); } catch (Exception ex) { if (ex is TaskCanceledException) { return; } Log.Warn(ex, "Task.Delay threw an exception"); } } }
public async Task GetsAsyncConversationError() { const string errorMessage = "Foo bar"; var conv = new CommandConversation(CommandType.Run); var responseMessage = ErrorResponseBuilder.Build(errorMessage); ICoreLink coreLink = GenerateCoreLink(responseMessage); var ex = await Assert.ThrowsAsync <RemoteCoreException>(() => coreLink.Request(conv, WaitMs)); Assert.Equal(errorMessage, ex.Message); }
public void GetsAsyncConversationResult() { var conversation = new CommandConversation(CommandType.Run); ResponseMessage responseMessage = StateResponseBuilder.Build(StateType.Running); ICoreLink coreLink = GenerateCoreLink(responseMessage); Task <StateResponse> futureResponse = coreLink.Request(conversation, WaitMs); StateResponse receivedResponse = ReadResponse(futureResponse); Assert.Equal(StateType.Running, receivedResponse.State); }
// TODO(HonzaS): Add filtering. private async Task RepeatGetModelAsync(CancellationTokenSource cancellation) { // TODO(HonzaS): If a command is in progress and visualization is fast enough, this actively waits (loops). // Can we replace this with another reset event? ModelResponse modelResponse = null; while (true) { if (await WaitForEvent(m_requestModelEvent, cancellation) == WaitEventResult.Cancelled) { return; } if (m_coreController.IsCommandInProgress) { continue; } try { // If there is no change to the filter, send null. ModelFilter filterToSend = m_filterChanged ? m_filter : null; m_filterChanged = false; // Request a model diff from the core. // TODO(HonzaS): Unless we lost connection or there was an error, request only incremental model (full: false). var modelResponseTask = m_coreLink.Request(new GetModelConversation(m_getFullModel, filterToSend, m_observerRequests), TimeoutMs).ConfigureAwait(false); m_getFullModel = false; // Wait until the model has been read. This happens before the first request as well. if (await WaitForEvent(m_modelReadEvent, cancellation) == WaitEventResult.Cancelled) { return; } // Wait for the previous diff to be applied to the new model (skip if this is the first request). if (modelResponse != null) { await ApplyModelDiffAsync(modelResponse); } // Wait for a new diff from the core. modelResponse = await modelResponseTask; // Apply current diff to the new model. await ApplyModelDiffAsync(modelResponse); // Allow visualization to read current (updated) model. m_isNewModelReady = true; } catch (Exception exception) { var timeoutException = exception as TaskTimeoutException <ModelResponse>; if (timeoutException != null) { // TODO(HonzaS): handle this. Wait for a while and then request a new full model state. Log.Error(timeoutException, "Model request timed out"); } else { // Keep trying for now. TODO(Premek): Do something smarter... Log.Error(exception, "Model retrieval failed"); } m_getFullModel = true; } } }