예제 #1
0
        public ITaskResult ReadResult(Type expectedResultValueType)
        {
            if (_methodContinuationData == null)
            {
                throw new InvalidOperationException();
            }

            var taskResult = TaskResult.CreateEmpty(expectedResultValueType);

            _valueContainerCopier.CopyValues(
                source: _methodContinuationData.Result,
                destination: (IValueContainer)taskResult);

            return(taskResult);
        }
예제 #2
0
        public async Task <ITaskResult> TryReadResultAsync(ServiceId serviceId, MethodId methodId, string intentId, Type resultValueType, CancellationToken ct)
        {
            var tableName = GetTableQualifiedName(serviceId, methodId);

            var key = new StorageRecord
            {
                service   = serviceId.Name,
                method    = methodId.Name,
                intent_id = intentId
            };

            var query = new StringBuilder("SELECT status, outcome, format, task_result, result, error FROM ")
                        .Append(tableName).Append(" WHERE ");

            WriteValues(query, key, delimiter: " AND ");

            var result = await ExecuteQueryAsync(serviceId, methodId, query.ToString());

            var row = result.FirstOrDefault();

            if (row == null)
            {
                return(null);
            }

            var record = ReadValues(row);

            if (!record.outcome.HasValue)
            {
                return(null);
            }

            if (record.outcome.Value == (int)Outcomes.Canceled)
            {
                return(TaskResult.Create(resultValueType, null, null, isCanceled: true));
            }

            var serializer = !string.IsNullOrEmpty(record.format)
                ? _serializerProvider.GetSerializer(record.format)
                : _serializer;

            var taskResult = TaskResult.CreateEmpty(resultValueType);

            serializer.Populate(record.task_result, (IValueContainer)taskResult);
            return(taskResult);
        }
예제 #3
0
        public Task <ITaskResult> TryReadResultAsync(ServiceId serviceId, MethodId methodId, string intentId, Type resultValueType, CancellationToken ct)
        {
            object serializedResultObj = null;

            lock (_entryMap)
            {
                if (!_entryMap.TryGetValue(intentId, out var entry) ||
                    !entry.TryGetValue("Result", out serializedResultObj))
                {
                    return(Task.FromResult <ITaskResult>(null));
                }
            }

            var result = TaskResult.CreateEmpty(resultValueType);

            _serializer.Populate((string)serializedResultObj, (IValueContainer)result);
            return(Task.FromResult(result));
        }
예제 #4
0
        public async Task <InvokeRoutineResult> InvokeAsync(
            MethodInvocationData data,
            InvocationPreferences preferences)
        {
            var message = new Message
            {
                Type = MessageType.InvokeMethod,
            };

            MethodInvocationDataTransformer.Write(message, data, _serializer);

            var result = new InvokeRoutineResult
            {
                Outcome = InvocationOutcome.Scheduled
            };

            if (preferences.Synchronous)
            {
                var completionNotification = new TaskCompletionSource <InvokeRoutineResult>();
                message.Data["Notification"] = completionNotification;

                _messageHub.Schedule(message);

                result = await completionNotification.Task;

                if (result.Result != null)
                {
                    result.Result = TaskResult.CreateEmpty(preferences.ResultValueType);
                    _serializer.Populate(_serializer.SerializeToString(result.Result), (IValueContainer)result.Result);
                }
            }
            else if (preferences.LockMessage)
            {
                result.MessageHandle = new MessageHandle(message, _messageHub);
            }
            else
            {
                _messageHub.Schedule(message);
            }

            return(result);
        }
예제 #5
0
        public async Task <ITaskResult> TryReadResultAsync(ServiceId serviceId, MethodId methodId, string intentId, Type resultValueType, CancellationToken ct)
        {
            var fileName = GetResultFileName(serviceId, methodId, intentId);
            var filePath = Path.Combine(_resultsDirectory, fileName);

            if (!File.Exists(filePath))
            {
                return(null);
            }

#if NETSTANDARD2_0
            var bytes = File.ReadAllBytes(filePath);
#else
            var bytes = await File.ReadAllBytesAsync(filePath);
#endif

            // TODO: select serializer
            var result = TaskResult.CreateEmpty(resultValueType);
            _serializer.Populate(bytes, (IValueContainer)result);
            return(result);
        }
예제 #6
0
        public async Task <InvokeRoutineResult> InvokeAsync(
            MethodInvocationData data,
            InvocationPreferences preferences)
        {
            HttpResponseMessage response;

            using (var requestContent = CreateContent(data))
            {
                requestContent.Headers.TryAddWithoutValidation(DasyncHttpHeaders.Envelope, "invoke");
                requestContent.Headers.TryAddWithoutValidation(DasyncHttpHeaders.IntentId, data.IntentId);
                AddAsyncHeader(requestContent.Headers, preferAsync: !preferences.Synchronous);
                AddCallerHeaders(requestContent.Headers, data.Caller);
                AddRetryHeader(requestContent.Headers, retryCount: 0);

                var url = _urlTemplate
                          .Replace("{serviceName}", data.Service.Name)
                          .Replace("{methodName}", data.Method.Name);

                response = await _httpClient.PostAsync(url, requestContent);
            }
            using (response)
            {
                if ((int)response.StatusCode == DasyncHttpCodes.Scheduled)
                {
                    return(new InvokeRoutineResult
                    {
                        Outcome = InvocationOutcome.Scheduled
                    });
                }

                if ((int)response.StatusCode == DasyncHttpCodes.Deduplicated)
                {
                    return(new InvokeRoutineResult
                    {
                        Outcome = InvocationOutcome.Deduplicated
                    });
                }

                var methodOutcome = response.Headers.GetValue(DasyncHttpHeaders.TaskResult);
                if (string.IsNullOrEmpty(methodOutcome))
                {
                    throw new Exception(); // TODO: add info
                }

                var responseStream = await response.Content.ReadAsStreamAsync();

                var encoding = response.Headers.GetContentEncoding();
                if (!string.IsNullOrEmpty(encoding))
                {
                    if ("gzip".Equals(encoding, StringComparison.OrdinalIgnoreCase))
                    {
                        responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
                    }
                    else if ("deflate".Equals(encoding, StringComparison.OrdinalIgnoreCase))
                    {
                        responseStream = new DeflateStream(responseStream, CompressionMode.Decompress);
                    }
                    else
                    {
                        throw new Exception($"Unknown content encoding '{encoding}'.");
                    }
                }

                using (responseStream)
                {
                    var taskResult = TaskResult.CreateEmpty(preferences.ResultValueType);
                    _serializer.Populate(responseStream, (IValueContainer)taskResult);

                    return(new InvokeRoutineResult
                    {
                        Outcome = InvocationOutcome.Complete,
                        Result = taskResult
                    });
                }
            }
        }
예제 #7
0
        public async Task <InvokeRoutineResult> GetInvocationResultAsync(
            ServiceId serviceId,
            MethodId methodId,
            string intentId,
            Type resultValueType,
            CancellationToken ct)
        {
            var url = _urlTemplate
                      .Replace("{serviceName}", serviceId.Name)
                      .Replace("{methodName}", methodId.Name)
                      + "/" + intentId;

            var request = new HttpRequestMessage
            {
                Method     = HttpMethod.Get,
                RequestUri = new Uri(url)
            };

            request.Headers.TryAddWithoutValidation(DasyncHttpHeaders.Envelope, "poll");

            if (_compressPayload)
            {
                request.Headers.TryAddWithoutValidation("Accept-Encoding", "gzip");
            }

            // TODO: add time for long polling
            //AddAsyncHeader(message.Headers, preferAsync: false, waitTime: );

            HttpResponseMessage response;

            using (request)
            {
                response = await _httpClient.SendAsync(request, ct);
            }

            using (response)
            {
                if ((int)response.StatusCode == DasyncHttpCodes.Running)
                {
                    return(new InvokeRoutineResult
                    {
                        Outcome = InvocationOutcome.Unknown
                    });
                }

                var methodOutcome = response.Headers.GetValue(DasyncHttpHeaders.TaskResult);
                if (string.IsNullOrEmpty(methodOutcome))
                {
                    throw new Exception(); // TODO: add info
                }

                var responseStream = await response.Content.ReadAsStreamAsync();

                var encoding = response.Headers.GetContentEncoding();
                if (!string.IsNullOrEmpty(encoding))
                {
                    if ("gzip".Equals(encoding, StringComparison.OrdinalIgnoreCase))
                    {
                        responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
                    }
                    else if ("deflate".Equals(encoding, StringComparison.OrdinalIgnoreCase))
                    {
                        responseStream = new DeflateStream(responseStream, CompressionMode.Decompress);
                    }
                    else
                    {
                        throw new Exception($"Unknown content encoding '{encoding}'.");
                    }
                }

                using (responseStream)
                {
                    var taskResult = TaskResult.CreateEmpty(resultValueType);
                    _serializer.Populate(responseStream, (IValueContainer)taskResult);

                    return(new InvokeRoutineResult
                    {
                        Outcome = InvocationOutcome.Complete,
                        Result = taskResult
                    });
                }
            }
        }