public async Task IncrementsExecutionCounterOnCallbackException() { var logger = A.Fake <ILogger>(); var eventStoreRepository = A.Fake <IMessageQueueRepository>(); A.CallTo(() => eventStoreRepository.GetDeadLetterListLength <TestMessage>()).Returns(1); var message = new TestMessage { Id = "0" }; A.CallTo(() => eventStoreRepository.GetUnprocessedMessage <TestMessage>(0)).Returns(JsonConvert.SerializeObject(message)); var retryData = new RetryData { LastRetryTime = DateTimeOffset.UtcNow.AddHours(-1) }; A.CallTo(() => eventStoreRepository.GetRetryData(A <TestMessage> ._)).Returns(retryData); var subscriber = A.Fake <IEventSubscriber>(); var retryClass = new TestExceptionRetryClass(subscriber, logger, eventStoreRepository); await retryClass.RetryAsync().ConfigureAwait(false);; A.CallTo(() => eventStoreRepository.UpdateRetryData(A <IMessage> ._, A <string> ._)).MustHaveHappened(); A.CallTo(() => logger.Log(LogLevel.Warning, 0, A <object> ._, null, A <Func <object, Exception, string> > ._)).MustHaveHappened(); A.CallTo(() => eventStoreRepository.DeleteFromDeadLetterQueue <TestMessage>(A <RedisValue> ._, A <IMessage> .That.Matches(x => x.Id == message.Id))).MustNotHaveHappened(); }
public async Task CallsCallbackIfTimeToLiveHasNotBeenExceeded() { var logger = A.Fake <ILogger>(); var eventStoreRepository = A.Fake <IMessageQueueRepository>(); A.CallTo(() => eventStoreRepository.GetDeadLetterListLength <TestMessage>()).Returns(1); var message = new TestMessage { Id = "0", TimeStamp = DateTimeOffset.UtcNow.AddHours(-1) }; A.CallTo(() => eventStoreRepository.GetUnprocessedMessage <TestMessage>(0)).Returns(JsonConvert.SerializeObject(message)); var retryData = new RetryData { LastRetryTime = DateTimeOffset.UtcNow.AddHours(-1), RetryCount = 6 }; A.CallTo(() => eventStoreRepository.GetRetryData(A <TestMessage> ._)).Returns(retryData); var subscriber = A.Fake <IEventSubscriber>(); var retryClass = new TestRetryHoursSubscription(subscriber, logger, eventStoreRepository); await retryClass.RetryAsync().ConfigureAwait(false); Assert.IsTrue(retryClass.CallBack1Called); A.CallTo(() => eventStoreRepository.DeleteFromDeadLetterQueue <TestMessage>(A <RedisValue> ._, A <IMessage> .That.Matches(x => x.Id == message.Id))).MustHaveHappened(); }
public async Task DoesNotFailWithLargeNumberOfRetries() { var logger = A.Fake <ILogger>(); var eventStoreRepository = A.Fake <IMessageQueueRepository>(); A.CallTo(() => eventStoreRepository.GetDeadLetterListLength <TestMessage>()).Returns(1); var message = new TestMessage { Id = "0", TimeStamp = DateTimeOffset.UtcNow.AddHours(-1) }; A.CallTo(() => eventStoreRepository.GetUnprocessedMessage <TestMessage>(0)).Returns(JsonConvert.SerializeObject(message)); var retryData = new RetryData { LastRetryTime = DateTimeOffset.UtcNow.AddHours(-1), RetryCount = 4000 }; A.CallTo(() => eventStoreRepository.GetRetryData(A <TestMessage> ._)).Returns(retryData); var subscriber = A.Fake <IEventSubscriber>(); var retryClass = new TestRetryHoursSubscription(subscriber, logger, eventStoreRepository); await retryClass.RetryAsync().ConfigureAwait(false); Assert.IsTrue(retryClass.CallBack1Called); }
public async Task CallsCallbackAndDeletesFromDeadLetterQueue() { var logger = A.Fake <ILogger>(); var eventStoreRepository = A.Fake <IMessageQueueRepository>(); A.CallTo(() => eventStoreRepository.GetDeadLetterListLength <TestMessage>()).Returns(3); var message1 = JsonConvert.SerializeObject(new TestMessage { Id = "0" }); var message2 = JsonConvert.SerializeObject(new TestMessage { Id = "1" }); var message3 = JsonConvert.SerializeObject(new TestMessage { Id = "2" }); A.CallTo(() => eventStoreRepository.GetUnprocessedMessage <TestMessage>(0)).ReturnsNextFromSequence(message1, message2, message3); var retryData = new RetryData { LastRetryTime = DateTimeOffset.UtcNow.AddHours(-1) }; A.CallTo(() => eventStoreRepository.GetRetryData(A <TestMessage> ._)).Returns(retryData); var subscriber = A.Fake <IEventSubscriber>(); var retryClass = new TestRetryClass(subscriber, logger, eventStoreRepository); await retryClass.RetryAsync().ConfigureAwait(false); Assert.IsTrue(retryClass.CallBack1Called); Assert.IsTrue(retryClass.CallBack2Called); Assert.IsTrue(retryClass.CallBack3Called); A.CallTo(() => eventStoreRepository.DeleteFromDeadLetterQueue <TestMessage>(A <RedisValue> ._, A <TestMessage> ._)) .MustHaveHappened(Repeated.Exactly.Times(3)); }
private IEnumerator MoveToWithMultipleTries(RoadData destination, float delay, RetryData retryData) { if (delay > 0.0f) { yield return(new WaitForSeconds(delay)); } string currentOrientation = _moveManager.orientation; Stack <RoadData> moveKeyPoints = null; int tries = 0; while (moveKeyPoints == null) { if (tries > 0) { yield return(new WaitForSeconds(UnityEngine.Random.Range(0.5f, 3.0f))); } moveKeyPoints = RoadsPathfinding.RouteStar(destination, occupiedRoad, _keyPointsModulo, currentOrientation); tries++; } _moveManager.Move(FollowMoveKeyPoints(moveKeyPoints, destination, retryData)); }
public async Task DoesNotCallCallbackIfRetryCounterIsGreaterThanThreshold() { var logger = A.Fake <ILogger>(); var eventStoreRepository = A.Fake <IMessageQueueRepository>(); A.CallTo(() => eventStoreRepository.GetDeadLetterListLength <TestMessage>()).Returns(1); var message = new TestMessage { Id = "0" }; A.CallTo(() => eventStoreRepository.GetUnprocessedMessage <TestMessage>(0)).Returns(JsonConvert.SerializeObject(message)); var retryData = new RetryData { LastRetryTime = DateTimeOffset.UtcNow.AddHours(-1), RetryCount = 6 }; A.CallTo(() => eventStoreRepository.GetRetryData(A <TestMessage> ._)).Returns(retryData); var subscriber = A.Fake <IEventSubscriber>(); var retryClass = new TestRetryClass(subscriber, logger, eventStoreRepository); await retryClass.RetryAsync().ConfigureAwait(false); Assert.IsFalse(retryClass.CallBack1Called); }
public void StuckSearchingHome(RetryData retryData) { //Debug.Log("STUCK SEARCHING "); if (_currentRoutine != null) //TODO { StopCoroutine(_currentRoutine); } _currentRoutine = StartCoroutine(SearchOtherHome()); }
/** * Fonctiona appelée par le onStuckEvent du RoadRouteManager de ce ResourceCarrier. **/ public void ResourceCarrierStuck(RetryData retryData)//ATTENTION: RetryData peut valoir null (si on essaie de se rendre à qqch de détruit) { if (collectingResources) { CollectingResourceCarrierStuck(retryData); } else { DeliveringResourceCarrierStuck(retryData); } }
/** * Lance le mouvement de l'objet vers destination après delay secondes. **/ public void MoveTo(RoadData destination, float delay, RetryData retryData) { if (destination == null) { onStuckEvent.Invoke(null); } if (occupiedRoad != destination) { StartCoroutine(MoveToWithMultipleTries(destination, delay, retryData)); } }
public async Task <RetryData> GetRetryData(IMessage @event) { var retryDataHashName = GetRetryDataHashKey(@event); var hashData = await _redisClient.HashGetAllAsync(retryDataHashName).ConfigureAwait(false); var lastRetryTime = hashData?.FirstOrDefault(x => x.Name == LastRetryTimeFieldName).Value; var retryCount = hashData?.FirstOrDefault(x => x.Name == RetryCountFieldName).Value; var data = new RetryData { RetryCount = retryCount == RedisValue.Null ? 0 : int.Parse(retryCount), LastRetryTime = lastRetryTime == RedisValue.Null ? DateTimeOffset.UtcNow : DateTimeOffset.Parse(lastRetryTime) }; return(data); }
public void OnStuck(RetryData retryData) { if (--_tryAgainToVisitHome == 0) { _continueTour = true; } else { if (goalFA != null) { GetComponent <RoadRouteManager>().MoveTo(goalFA.road); } else { Debug.Log("if you see this, I'm a prefect and I'm stuck, I won't move again, and this is real real bad !"); } } }
public async Task <OnchainResponse> RetryAsync(RetryData data) { var request = new RetryFailedRequest(data.TransactionId); var response = await _apiClient.ApiEnqueueTransactionRetryPostAsync(request); if (response != null) { return new OnchainResponse { Error = new ErrorResponse { Code = response.Error.Code, Message = response.Error.Message } } } ; return(new OnchainResponse()); }
public void CollectingResourceCarrierStuck(RetryData retryData)//ATTENTION: RetryData peut valoir null (si on essaie de se rendre à qqch de détruit) { RoadRouteManager routeManager = GetComponent <RoadRouteManager>(); if (destination == null && origin == null) //bâtiment de destination détruit, et l'origine est détruite { collectingResources = false; //Pour être sûr de ne pas refiler les ressources à l'autre maison et faire ainsi confusion avec son/ses transporteur(s) StartCoroutine(GoHome()); //On part se faire éliminer dans la maison la plus proche. } else//Dans tous les autre cas, on retourne à l'origine (soit on s'obstine, soit on fait demi-tour) { if (destination != origin && destination != null) { destination.GetComponent <KeepAsideOrderManager>().CancelKeptAside(this); } destination = origin; routeManager.MoveTo(destination.freightAreaData.freightAreaIn.road); } }
public IAsyncReactiveQbserver <T> GetHttpFinalObserver <T>( string method, Uri onCompleted, Uri onError, Tuple <string, string>[] headers, RetryData retryData, TimeSpan timeout) { if (string.IsNullOrEmpty(method)) { throw new ArgumentNullException(nameof(method)); } if (onCompleted == null) { throw new ArgumentNullException(nameof(onCompleted)); } if (onError == null) { throw new ArgumentNullException(nameof(onError)); } if (retryData == null) { throw new ArgumentNullException(nameof(retryData)); } if (timeout < TimeSpan.Zero) { throw new ArgumentOutOfRangeException(nameof(timeout), timeout, "timeout less than zero"); } var observer = GetObserver <string, Uri, Uri, Tuple <string, string>[], RetryData, TimeSpan, T>(Constants.Observer.Final.Http.Uri); return(observer(method, onCompleted, onError, headers, retryData, timeout)); }
public void DeliveringResourceCarrierStuck(RetryData retryData)//ATTENTION: RetryData peut valoir null (si on essaie de se rendre à qqch de détruit) { RoadRouteManager roadRouteManager = GetComponent <RoadRouteManager>(); if (destination != null)//destination peut valoir null si le bâtiment a été détruit { ResourceConsumer consumer = destination.freightAreaData.parentStock.GetComponent <ResourceConsumer>(); if (shipment != null && consumer != null && origin.freightAreaData.freightAreaIn != destination)//Donc: si le transporteur est en livraison vers un ResourceConsumer et qu'il n'est pas déjà en cours de mouvement d'annulation de livraison { consumer.CancelResourceOrder(shipment); } } if (origin != null) { destination = origin; roadRouteManager.MoveTo(destination.freightAreaData.freightAreaIn.road, Random.Range(0.5f, 3.0f), null); } else { StartCoroutine(GoHome()); } }
private IEnumerator <MoveDescriptor> FollowMoveKeyPoints(Stack <RoadData> moveKeyPoints, RoadData finalDestination, RetryData retryData) { RoadData lastKeyPoint = occupiedRoad; foreach (RoadData keyPoint in moveKeyPoints) { if (keyPoint != null && keyPoint.Neighbors().Contains(occupiedRoad)) { AnticipateNextOrientation(occupiedRoad, keyPoint, _moveManager.orientation); } RoadData lastRoad = occupiedRoad; while (occupiedRoad != keyPoint) { string currentOrientation = _moveManager.orientation; Stack <RoadData> roadPath = RoadsPathfinding.RoadPathStar(keyPoint, occupiedRoad, _keyPointsModulo, currentOrientation, finalDestination); if (roadPath == null)//On annule cet énumérateur et on relance la recherche { if (retryData == null) { retryData = new RetryData(lastKeyPoint, finalDestination); } retryData.IncrementCounter(); _moveManager.CancelMove(); if (retryData.triesCounter == MAX_MOVE_TRIES) { onStuckEvent.Invoke(retryData); } else { MoveTo(finalDestination, UnityEngine.Random.Range(0.25f, 1.5f), retryData); //Ce qui relance donc une coroutine qui va s'occuper de ça! } yield break; } else if (roadPath.Count == 0) { break; //Si le roadPath est vide, c'est qu'on est déjà à destination, ou suffisamment proche de celle-ci pour passer au prochain keyPoint } RoadData nextRoad = roadPath.Pop(); if (nextRoad != lastRoad || UnityEngine.Random.Range(1, 100) == 1) { foreach (RoadData toReserve in roadPath) { toReserve.roadLock.reservationsNber++; } MoveDescriptor toApply = new MoveDescriptor(nextRoad.transform.position, occupiedRoad.transform.position, speed, 0.1f); string orientationToUnlock = currentOrientation; if (MovementWithoutUnshift(occupiedRoad.roadLock, currentOrientation, toApply))//Partage la case avec un autre dans une orientation contraire { _moveManager.UseShiftForMovement(toApply); } else if (occupiedRoad.roadLock.split != RoadLock.DIAGONAL_SPLIT)//!NoNeedToRelock()) { occupiedRoad.roadLock.UnlockFor(currentOrientation, gameObject); occupiedRoad.roadLock.LockFor(toApply.orientation, gameObject); orientationToUnlock = toApply.orientation; } nextRoad.roadLock.LockFor(toApply.orientation, gameObject); //+++++> C'est la ligne ci-dessus qui est chiante: avec un diag split, on risque de relocker dans la mme direction que le contenu principal...>TROUVER UNE SOLUTION //>>>> cas de double split à gérer via une condition spéciale (offre spéciale, SUPER PROMO) dans le RoadLock (avec qques var globales :/) yield return(toApply); lastRoad = occupiedRoad; occupiedRoad.roadLock.UnlockFor(orientationToUnlock, gameObject); occupiedRoad = nextRoad; foreach (RoadData toFree in roadPath) { toFree.roadLock.reservationsNber--; } if (roadPath.Count != 0)//Donc, s'il y a encore une case sur laquelle bouger par la suite jusqu'au prochain keypoint { RoadData secondNextRoad = roadPath.Pop(); AnticipateNextOrientation(nextRoad, secondNextRoad, toApply.orientation); } } else { yield return(null); } } lastKeyPoint = keyPoint; } yield return(null); }