protected override Task <RequestStatus> HandleCommand(CancelBidCommand request, CancellationToken cancellationToken) { var auction = FindAuction(request); var bid = FindBid(request, auction); var user = FindUser(request); auction.CancelBid(user, bid); var transactionOpt = new TransactionOptions() { IsolationLevel = IsolationLevel.Serializable, Timeout = TimeSpan.FromSeconds(10) }; using (var scope = new TransactionScope(TransactionScopeOption.Required, transactionOpt)) { _auctionRepository.UpdateAuction(auction); _userRepository.UpdateUser(user); scope.Complete(); } _eventBusService.Publish(auction.PendingEvents.Concat(user.PendingEvents), request.CommandContext.CorrelationId, request); auction.MarkPendingEventsAsHandled(); user.MarkPendingEventsAsHandled(); return(Task.FromResult(RequestStatus.CreateFromCommandContext(request.CommandContext, Status.COMPLETED))); }
public void Queue_Processing_CorruptedEvent() { // Enqueue events for further handling bus.Subscribe(testService.Enque <TestEvent>()); // except test to throw Exception event Exception exception = null; bus.Subscribe <Exception>(e => exception = e); int counter = 0; int backofIntervalMs = 50; // Subscribe handler which waits 50 ms Delegate <TestEvent> handler = (e) => { counter++; throw new NotImplementedException(); }; bus.Subscribe(handler.WhenQueued().RetryQueued(3, Backoff.Fixed(TimeSpan.FromMilliseconds(backofIntervalMs)) )); bus.Publish(new TestEvent(), this); // There is event to handle Assert.AreEqual(1, repository.Queue.Where(e => e.DeclaringEventType == typeof(TestEvent).AssemblyQualifiedName).Count()); testService.ProcessEvents(); Assert.AreEqual(0, repository.Queue.Where(e => e.DeclaringEventType == typeof(TestEvent).ToString()).Count()); Assert.IsNotNull(exception); Assert.IsInstanceOfType(exception, typeof(FormatException)); }
protected override Task <RequestStatus> HandleCommand(SignUpCommand request, CancellationToken cancellationToken) { var existing = _userAuthenticationDataRepository.FindUserAuth(request.Username); if (existing != null) { throw new UsernameConflictException($"User {request.Username} already exists"); } var user = new User(); user.Register(request.Username); var response = RequestStatus.CreateFromCommandContext(request.CommandContext, Status.COMPLETED); var userAuth = new UserAuthenticationData() { Password = request.Password, UserId = user.UserIdentity.UserId, UserName = user.UserIdentity.UserName, Email = request.Email }; _userAuthenticationDataRepository.AddUserAuth(userAuth); _userRepository.AddUser(user); _eventBusService.Publish(user.PendingEvents, response.CorrelationId, request); user.MarkPendingEventsAsHandled(); return(Task.FromResult(response)); }
protected override Task <RequestStatus> HandleCommand(UpdateAuctionCommand request, CancellationToken cancellationToken) { var auction = GetAuction(request); if (!auction.Owner.UserId.Equals(request.SignedInUser.UserId)) { throw new UnauthorizedAccessException($"User is not owner of an auction {auction.AggregateId}"); } auction.UpdateTags(request.Tags.Select(s => new Tag(s)).ToArray()); auction.UpdateName(request.Name); auction.UpdateBuyNowPrice(request.BuyNowPrice); auction.UpdateDescription(request.Description); if (request.EndDate != null) { auction.UpdateEndDate(request.EndDate); } var newCategory = _categoryBuilder.FromCategoryNamesList(request.Category); auction.UpdateCategory(newCategory); var response = RequestStatus.CreateFromCommandContext(request.CommandContext, Status.PENDING); _auctionRepository.UpdateAuction(auction); _eventBusService.Publish(auction.PendingEvents, response.CorrelationId, request); return(Task.FromResult(response)); }
protected override Task <RequestStatus> HandleCommand(BuyNowCommand request, CancellationToken cancellationToken) { var user = _userRepository.FindUser(request.SignedInUser); if (user == null) { _logger.LogError("BuyNowCommandHandler cannot find user {@user}", request.SignedInUser); throw new CommandException($"Cannot find user: {user.UserIdentity}"); } var auction = _auctionRepository.FindAuction(request.AuctionId); if (auction == null) { throw new CommandException($"Invalid auction id: {request.AuctionId}"); } var buyNowService = new BuyNowService(_userRepository); var generatedEvents = buyNowService.BuyNow(auction, user); generatedEvents.AddRange(auction.PendingEvents); generatedEvents.AddRange(user.PendingEvents); _auctionRepository.UpdateAuction(auction); _userRepository.UpdateUser(user); _eventBusService.Publish(generatedEvents, request.CommandContext.CorrelationId, request); return(Task.FromResult(RequestStatus.CreateFromCommandContext(request.CommandContext, Status.PENDING))); }
protected virtual void SubscribeForRequeueStuckEvents(EventBusService eventBus) { eventBus.Subscribe(Enque <RequeueStuckEvents>(TimeSpan.FromSeconds(40))); eventBus.Subscribe(this.WhenQueued()); // enqueue a first event eventBus.Publish(new RequeueStuckEvents(), this); }
private void ReplaceAuctionImage(UserReplaceAuctionImageCommand request, CancellationToken cancellationToken, CorrelationId correlationId) { var auction = _auctionRepository.FindAuction(request.AuctionId); if (auction == null) { throw new CommandException($"Cannot find auction {request.AuctionId}"); } var file = File.ReadAllBytes(request.TempPath); File.Delete(request.TempPath); var img = new AuctionImageRepresentation(new AuctionImageMetadata(request.Extension), file); var newImg = _auctionImageService.AddAuctionImage(img); auction.ReplaceImage(newImg, request.ImgNum); _auctionRepository.UpdateAuction(auction); try { _eventBusService.Publish(auction.PendingEvents, correlationId, request); } catch (Exception) { _auctionImageService.RemoveAuctionImage(newImg); throw; } }
protected override Task <RequestStatus> HandleCommand(BuyCreditsCommand request, CancellationToken cancellationToken) { //DEMO if (request.Ammount != 15 && request.Ammount != 40 && request.Ammount != 100) { throw new InvalidCommandException($"Invalid amount value: {request.Ammount}"); } var user = _userRepository.FindUser(request.SignedInUser); if (user == null) { throw new CommandException("Cannot find user"); } user.AddCredits(request.Ammount); _userRepository.UpdateUser(user); _eventBusService.Publish(user.PendingEvents, request.CommandContext.CorrelationId, request); user.MarkPendingEventsAsHandled(); var status = RequestStatus.CreateFromCommandContext(request.CommandContext, Status.PENDING); return(Task.FromResult(status)); }
public virtual void Handle(RequeueStuckEvents e) { try { _repository.RequeueOldEvents(RequeueTimeLimit); } finally { _eventBusService.Publish(e.Clone(), this); } }
public void Callback(IAsyncResult result) { try { _handler.EndInvoke(result); } catch (Exception ex) { _eventBusService.Publish <Exception>(ex, this); } }
/// <summary> /// Thos method used to publish event and handle exception, if happened /// </summary> /// <param name="item"></param> protected virtual void onProcessQueueItem(IQueueItem item) { MethodInfo genericMethod; object typedEvent; object sender; // Any exception within following try/catch block is final // report exception for handing and remove event from queue as failed try { genericMethod = GetPublishMethodInfo(item.DeclaringEventType); typedEvent = BuildGenericQueueEvent(item); sender = BuildSender(item.DeclaringEventType); } catch (Exception ex) { onEventFailed(item, ex); _eventBusService.Publish <Exception>(ex, this); return; } // Event handling here try { genericMethod.Invoke(_eventBusService, new[] { typedEvent, sender }); onEventHandled(item); } // Exceptions from actual delegate are wrapped into TargetInvocationException by MethodBase.Invoke() catch (TargetInvocationException ex) { RetryNeededException retry = ex.InnerException as RetryNeededException; if (retry != null) { onEventRetried(item, retry); } else { onEventFailed(item, ex.InnerException); } } }
protected override Task <RequestStatus> HandleCommand(EndAuctionCommand request, CancellationToken cancellationToken) { var auction = _auctionRepository.FindAuction(request.AuctionId); auction.EndAuction(); _eventBusService.Publish(auction.PendingEvents, null, request); auction.MarkPendingEventsAsHandled(); var response = RequestStatus.CreateFromCommandContext(request.CommandContext, Status.COMPLETED); return(Task.FromResult(response)); }
private void RemoveAuctionImage(UserRemoveAuctionImageCommand request, CancellationToken cancellationToken, CorrelationId correlationId) { var auction = _auctionRepository.FindAuction(request.AuctionId); if (auction == null) { throw new CommandException($"Cannot find auction {request.AuctionId}"); } auction.RemoveImage(request.ImgNum); _auctionRepository.UpdateAuction(auction); _eventBusService.Publish(auction.PendingEvents, correlationId, request); }
private void AddImage(UserAddAuctionImageCommand request, CancellationToken cancellationToken, CorrelationId correlationId) { var auction = _auctionRepository.FindAuction(request.AuctionId); if (auction == null) { throw new CommandException($"Cannot find auction {request.AuctionId}"); } if (!auction.Owner.UserId.Equals(request.SignedInUser.UserId)) { throw new CommandException( $"User {request.SignedInUser.UserId} cannot modify auction ${auction.AggregateId}"); } var file = File.ReadAllBytes(request.TempPath); File.Delete(request.TempPath); var img = new AuctionImageRepresentation(new AuctionImageMetadata(request.Extension), file); var newImg = _auctionImageService.AddAuctionImage(img); auction.AddImage(newImg); _auctionRepository.UpdateAuction(auction); try { _eventBusService.Publish(auction.PendingEvents, correlationId, request); } catch (Exception e) { _logger.LogWarning(e, "Error while trying to publish events"); _auctionImageService.RemoveAuctionImage(newImg); throw; } }
protected override Task <RequestStatus> HandleCommand(BidCommand request, CancellationToken cancellationToken) { var auction = _auctionRepository.FindAuction(request.AuctionId); if (auction == null) { throw new CommandException("Invalid auction id"); } var user = _userRepository.FindUser(request.SignedInUser); if (user == null) { throw new CommandException($"Cannot find user {request.SignedInUser.UserName}"); } auction.Raise(user, request.Price); var bid = auction.Bids.Last(); var response = RequestStatus.CreateFromCommandContext(request.CommandContext, Status.PENDING); _auctionRepository.UpdateAuction(auction); _userRepository.UpdateUser(user); var toSend = auction.PendingEvents.Concat(user.PendingEvents); _eventBusService.Publish(toSend, response.CorrelationId, request); _requestStatusService.TrySendNotificationToAll("AuctionPriceChanged", new Dictionary <string, object>() { { "winningBid", bid } }); auction.MarkPendingEventsAsHandled(); _logger.LogDebug("Bid {@bid} submited for an auction {@auction} by {@user}", bid, auction, request.SignedInUser); return(Task.FromResult(response)); }
public void Queue_ProcessingTimelimit() { // Enqueue events for further handling bus.Subscribe(testService.Enque <TestEvent>()); // Subscribe handler which waits 50 ms bus.Subscribe <QueuedEvent <TestEvent> >((e) => Task.Delay(50).Wait()); for (int i = 0; i < 10; i++) { bus.Publish(new TestEvent(), this); } // expect to handle no more than 5 events testService.ProcessingTimeLimit = TimeSpan.FromMilliseconds(249); var result = testService.ProcessEvents(); Console.Write($"Number of items processed: {result.Processed}"); Assert.IsTrue(4 == result.Processed || 5 == result.Processed); }