예제 #1
0
        public void TryToAdd(CommandRegistryItem item, CancellationToken cancellationToken = default)
        {
            if (_inner.Where(x => !string.IsNullOrEmpty(item.Key) && x.Value.Key == item.Key && x.Value.State < CommandRegistryItemState.Cancelled).Any())
            {
                throw new ConcurrencyException();
            }

            item.CancellationToken = cancellationToken;
            item.SetConflictingIds(GetIdsOfConflictingIncompleteRequests(item));
            item.Index = _inner.Count() + 1;
            _inner.TryAdd(item.CorrelationId, item);
        }
        public async Task <IActionResult> Post(CancellationToken cancellationToken = default)
        {
            var authorizationResult = await _authorizationService.AuthorizeAsync(_httpContextAccessor.HttpContext.User, new AuthorizationPolicyBuilder()
                                                                                 .RequireAuthenticatedUser()
                                                                                 .Build());

            var item = await CommandRegistryItem.ParseAsync(Request);

            if (!authorizationResult.Succeeded && !item.hasAllowAnonymousAttribute)
            {
                return(new UnauthorizedResult());
            }

            var syncLock = _locks.GetOrAdd($"{item.PartitionKey}", id => new object());

            lock (syncLock)
                _commandRegistry.TryToAdd(item);

            if (item.HasConflicts())
            {
                await Observable.Zip(_commandRegistry
                                     .GetByCorrelationIds(item.ConflictingIds.Split(','))
                                     .Select(x => x.Completed));
            }

            dynamic result = default;

            try
            {
                result = await _mediator.Send(JsonConvert.DeserializeObject(item.Request, Type.GetType(item.RequestDotNetType)) as dynamic);

                item.Complete();
            }
            catch (Exception e)
            {
                item.Error();

                throw e;
            }

            return(new JsonResult(result));
        }
예제 #3
0
 public void Remove(CommandRegistryItem item)
 => _inner.TryRemove(item.CorrelationId, out _);
예제 #4
0
 private string GetIdsOfConflictingIncompleteRequests(CommandRegistryItem item)
 => string.Join(",", GetAllIncomplete(item.PartitionKey)
                .Where(incompleteRequest => item.ConflictsWith(incompleteRequest))
                .Select(x => x.CorrelationId));