public override void PostSave(Saga saga, SagaContext commit, Exception error) { }
public void RunsTakeSagaWaitingForAction() { //Arrange var runner = new Saga(); var enumerator = runner.Run(this.RootSaga()); //Act SagaAction returnData = null; runner.OnActionEvent += (data) => { returnData = data; }; for (var i = 0; i < 100; i++) { enumerator.MoveNext(); } //Assert Assert.IsNull(returnData); runner.OnAction(new SagaAction <int>("start", 11)); for (var i = 0; i < 100; i++) { enumerator.MoveNext(); } //Assert Assert.AreEqual("test", returnData.Type); Assert.AreEqual(11, returnData.GetPayload <int>()); }
protected override void OnRegister(Saga.Templates.BaseNPC npc) { RegisterDialog(npc, DialogType.Smith, new FunctionCallback(OnBlackSmithMenu)); RegisterDialog(npc, DialogType.Smith, 50, new FunctionCallback(OnRepairEquipment)); RegisterDialog(npc, DialogType.Smith, 53, new FunctionCallback(OnUpgradeWeapon)); RegisterDialog(npc, DialogType.Smith, 55, new FunctionCallback(OnChangeWeaponSuffix)); }
public IDataReader ExecuteDataReader(Saga.Data.IQueryProvider query, CommandBehavior behavior) { MySqlConnection connection = ConnectionPool.Request(); MySqlCommand command = new MySqlCommand(); MySqlDataReader reader = null; try { command.CommandText = query.CmdText; command.Connection = connection; foreach (KeyValuePair<string, object> pair in query.Parameters) { command.Parameters.AddWithValue(pair.Key, pair.Value); } return command.ExecuteReader(behavior); } catch (Exception e) { __dbtracelog.WriteError("Database", e.Message); return null; } finally { //ALWAYS CLOSE THE CONNECTION AND REPOOL THE ITEMS if (reader != null && reader.IsClosed == false) reader.Close(); ConnectionPool.Release(connection); } }
public int ExecuteNonQuery(Saga.Data.IQueryProvider query) { //HELPER VARIABLES MySqlConnection connection = ConnectionPool.Request(); MySqlCommand command = new MySqlCommand(); try { command.CommandText = query.CmdText; command.Connection = connection; foreach (KeyValuePair<string, object> pair in query.Parameters) { command.Parameters.AddWithValue(pair.Key, pair.Value); } return command.ExecuteNonQuery(); } catch (Exception e) { __dbtracelog.WriteError("Database", e.Message); return 0; } finally { //ALWAYS CLOSE THE CONNECTION AND REPOOL THE ITEMS ConnectionPool.Release(connection); } }
public void RemoveSaga <TMessage>(Saga <TSagaData> saga) { var finder = _factory.Create <TSagaData, TMessage>(); // Refactor ((ISagaDataFinderBase <TSagaData>)finder).RemoveSagaData(saga.Data); }
// Use this for initialization void Start() { var saga = new Saga(); saga.OnActionEvent += Saga_OnActionEvent; this.StartCoroutine(saga.Run(this.RootSaga())); }
public LastNameRouteBuilder(Saga saga, string name) { _saga = saga; _name = name; _channels = new List <Channel>(); }
public void Dispatch(IEnvelope envelope) { var actor = Agent.GetActor(envelope.CorrelationId); var message = (TMessage)envelope.Message; Saga.Process(actor, message); Agent.Memoize(actor); }
/// <summary> /// Attempt to retrieve an existing saga instance identified by the specified <paramref name="type"/> and <paramref name="id"/>. /// </summary> /// <param name="type">The type of saga to be retrieved.</param> /// <param name="id">The correlation id of the saga to be retrieved.</param> /// <param name="saga">The <see cref="Saga"/> instance if found; otherwise <value>null</value>.</param> public Boolean TryGetSaga(Type type, Guid id, out Saga saga) { var result = sagaStore.TryGetSaga(type, id, out saga); statistics.IncrementQueryCount(); return(result); }
public void Continue(object message, Saga saga, Route route) { var adapter = _factory.Create <IMessageAdapter>(_configuration.MessageAdapterType); var interceptor = _factory.Create <IRouterInterceptor>(_configuration.RouterInterceptorType); var context = adapter.Read(message, route.ContentType); var when = true; if (route.When != null) { when = route.When(context); } if (when) { interceptor.OnEntry(context); try { var middlewares = new List <Type> { typeof(MessageExceptionHandler) }; middlewares.AddRange(_configuration.InboundMiddlewareTypes); middlewares.AddRange(route.MiddlewareTypes); middlewares.Add(typeof(NextMessageHandler)); var parameter = new MiddlewareParameter() { Route = route, Saga = saga }; context.Route = route; context.Saga = saga; var pipeline = new Pipeline(_factory, middlewares.ToArray(), context, parameter); pipeline.Execute(); interceptor.OnSuccess(context); } catch (Exception ex) { interceptor.OnException(context, ex); throw; } finally { interceptor.OnExit(context); } } }
public void ExceptionWithoutTryShouldCrashTheProcess() { //Arrange var runner = new Saga(); //Assert Assert.Catch <NotImplementedException>( () => this.RunSaga(runner, this.DoStuff(new Ref <int>(), true))); }
internal ActiveSagaInstance(Saga saga, SagaMetadata metadata, Func<DateTime> currentUtcDateTimeProvider) { this.currentUtcDateTimeProvider = currentUtcDateTimeProvider; Instance = saga; Metadata = metadata; Created = currentUtcDateTimeProvider(); Modified = Created; }
/// <summary> /// Gets (most likely from a cache) the set of correlation properties relevant for the given saga handler. /// </summary> public SagaDataCorrelationProperties GetCorrelationProperties(object message, Saga saga) { var sagaDataType = saga.GetSagaDataType(); var correlationPropertiesForThisSagaDataType = _cachedCorrelationProperties .GetOrAdd(sagaDataType, type => GetCorrelationProperties(saga)); return new SagaDataCorrelationProperties(correlationPropertiesForThisSagaDataType, sagaDataType); }
static void AddEntity(ILogger logger, Saga saga, List <LogEventProperty> properties) { if (!logger.BindProperty("Entity", saga.Entity, out var sagaEntityProperty)) { return; } properties.Add(sagaEntityProperty); }
public void MessageReceived() { var data = new OldCacheUpdateRequest() { RequestingUri = new Uri("msmq://bob/bill") }; Saga.RaiseEvent(LegacySubscriptionClientSaga.OldCacheUpdateRequested, data); }
/// <summary> /// When overriden, defines the custom behavior to be invoked after attempting to save the specified <paramref name="saga"/>. /// </summary> /// <param name="saga">The modified <see cref="Saga"/> instance if <paramref name="error"/> is <value>null</value>; otherwise the original <see cref="Saga"/> instance if <paramref name="error"/> is not <value>null</value>.</param> /// <param name="context">The current <see cref="SagaContext"/> assocaited with the pending saga modifications.</param> /// <param name="error">The <see cref="Exception"/> thrown if the save was unsuccessful; otherwise <value>null</value>.</param> public override void PostSave(Saga saga, SagaContext context, Exception error) { base.PostSave(saga, context, error); if (error is ConcurrencyException) { statistics.IncrementConflictCount(); } }
/// <summary> /// Creates a new <see cref="ActiveSagaInstance"/> instance. /// </summary> public ActiveSagaInstance(Saga saga, SagaMetadata metadata, Func <DateTime> currentUtcDateTimeProvider) { this.currentUtcDateTimeProvider = currentUtcDateTimeProvider; Instance = saga; Metadata = metadata; Created = currentUtcDateTimeProvider(); Modified = Created; }
public void TestMultipleCommits() { // Arrange Mock <Action> rollbackStep1 = new Mock <Action>(); rollbackStep1.Setup(m => m()); Mock <Action> rollbackStep2 = new Mock <Action>(); rollbackStep1.Setup(m => m()); Mock <Action> rollbackStep3 = new Mock <Action>(); rollbackStep1.Setup(m => m()); Mock <Action> rollbackStep4 = new Mock <Action>(); rollbackStep4.Setup(m => m()); Exception exception = null; // Act try { using (Saga saga = new Saga()) { DoStep1(); saga.RegisterCompensation(rollbackStep1.Object); saga.Commit(); DoStep2(); saga.RegisterCompensation(rollbackStep2.Object); DoStep3(); saga.RegisterCompensation(rollbackStep3.Object); DoStep4(); saga.RegisterCompensation(rollbackStep4.Object); saga.Commit(); } } catch (Exception ex) { exception = ex; } // Assert Assert.IsInstanceOfType(exception, typeof(ApplicationException)); rollbackStep1.Verify(m => m(), Times.Never); rollbackStep2.Verify(m => m(), Times.Once); rollbackStep3.Verify(m => m(), Times.Once); rollbackStep4.Verify(m => m(), Times.Never); }
private async Task PublishCommandsAsync(Saga saga) { var messages = saga.GetUndispatchedCommands().Select(command => { dynamic typeAwareCommand = command; //this cast is required to pass the correct Type to the Notify Method. Otherwise IEvent is used as the Type return((Task)_commandDispatcher.SendAsync(typeAwareCommand)); }); await Task.WhenAll(messages); saga.ClearUndispatchedCommands(); }
public void test_01_all_movements_succeed_in_first_setp() { var movements = new List <Movement> { GetSuccesfullMovement(), GetSuccesfullMovement() }; Saga.Start(movements).Should().BeTrue(); movements.Select(x => x.InProcess).Should().AllBeEquivalentTo(true); movements.Select(x => x.IsSuccesfull).Should().AllBeEquivalentTo(false); }
protected override void OnBlackSmithMenu(BaseNPC npc, Saga.PrimaryTypes.Character target) { Common.Actions.OpenSubmenu(target, npc, _BlackSmithMenu, //Dialog script to show DialogType.Smith, //Button function 50, //Repair 53, //Upgrade 55 //Change Suffix ); }
protected void RunSaga(Saga runner, IEnumerator sagaToRun) { //Arrange var enumerator = runner.Run(sagaToRun); while (enumerator.MoveNext()) { ; } }
public void test_03_last_movement_fails_so_all_rollback() { var movements = new List <Movement> { GetSuccesfullMovement(), GetFailedMovement() }; Saga.Start(movements); movements[0].IsRollback.Should().BeTrue(); movements.Select(x => x.Started).Should().AllBeEquivalentTo(true); movements.Select(x => x.InProcess).Should().AllBeEquivalentTo(false); }
public override void OnLeave(Saga.PrimaryTypes.Character character) { //Removes the actor from the shipzone base.OnLeave(character); //Always force to leave from shipzone character.map = this.CathelayaLocation.map; character.Position = this.CathelayaLocation.coords; System.Console.WriteLine("{0} {1}", this.CathelayaLocation.map, this.CathelayaLocation.coords); }
/// <summary> /// Opens the bookstore. /// </summary> /// <param name="character">Character to show the bookstore</param> /// <param name="basenpc">Npc providing the bookstore</param> public override void Open(Saga.PrimaryTypes.Character character, Saga.Templates.BaseNPC basenpc) { character.Tag = this; SMSG_SENDBOOKLIST spkt = new SMSG_SENDBOOKLIST(); spkt.SessionId = character.id; spkt.SourceActor = basenpc.id; spkt.Zeny = basenpc.Zeny; foreach (BaseShopCollection.ShopPair c in this.list) spkt.Add(c.item.info.item); character.client.Send((byte[])spkt); }
public UpdateProcessLevyDeclarationsSagaProgressCommandHandlerTestsFixture SetScheduledSagaType() { Saga.Set(s => s.Type, LevyDeclarationSagaType.Planned) .Set(s => s.AccountPayeSchemeHighWaterMarkId, AccountPayeSchemes.Max(aps => aps.Id)) .Set(s => s.ImportPayeSchemeLevyDeclarationsTasksCount, AccountPayeSchemes.Select(aps => aps.EmployerReferenceNumber).Count()) .Set(s => s.UpdateAccountTransactionBalancesTasksCount, AccountPayeSchemes.Select(aps => aps.AccountId).Distinct().Count()); Db.SaveChanges(); return(this); }
private ISagaWithCreatedOn GetSagaData(Saga saga) { var property = _sagaDataCache.GetOrAdd(saga.GetType(), x => saga.GetType().GetProperty(nameof(Saga <ISagaData> .Data))); var data = property.GetValue(saga) as ISagaWithCreatedOn; Guard.Against <InvalidOperationException>(data == null, $"SagaData for saga {saga.GetType()} does not implemente {nameof(ISagaWithCreatedOn)}?!" ); return(data); }
/// <summary> /// Gets (most likely from a cache) the set of correlation properties relevant for the given saga handler. /// </summary> public SagaDataCorrelationProperties GetCorrelationProperties(object message, Saga saga) { var sagaType = saga.GetType(); var sagaDataType = saga.GetSagaDataType(); var key = $"{sagaType.FullName}/{sagaDataType.FullName}"; var correlationPropertiesForThisSagaDataType = _cachedCorrelationProperties .GetOrAdd(key, _ => GetCorrelationProperties(saga)); return(new SagaDataCorrelationProperties(correlationPropertiesForThisSagaDataType, sagaDataType)); }
public SagaProcess(string name, Saga saga, IEnumerator enumerator, bool isSynchronous) { this.Name = name; this.Saga = saga; this.subProcesses = new Queue <SagaProcess>(); this.runningProcesses = new List <SagaProcess>(); this.IsSynchronous = isSynchronous; this.HasEnumeratorFinished = false; this.processEnumerator = Utils.Flatten(enumerator); this.processQueue = this.CreateProcessQueue(); }
public UpdateProcessLevyDeclarationsSagaProgressCommandHandlerTestsFixture SetAdHocSagaType() { Saga.Set(s => s.Type, LevyDeclarationSagaType.AdHoc) .Set(s => s.AccountPayeSchemeId, AccountPayeSchemes[0].Id) .Set(s => s.ImportPayeSchemeLevyDeclarationsTasksCount, 1) .Set(s => s.UpdateAccountTransactionBalancesTasksCount, 1); Db.SaveChanges(); return(this); }
/// <summary> /// Gets (most likely from a cache) the set of correlation properties relevant for the given saga handler. /// </summary> public SagaDataCorrelationProperties GetCorrelationProperties(object message, Saga saga) { var sagaType = saga.GetType(); var sagaDataType = saga.GetSagaDataType(); var key = $"{sagaType.FullName}/{sagaDataType.FullName}"; var correlationPropertiesForThisSagaDataType = _cachedCorrelationProperties .GetOrAdd(key, _ => GetCorrelationProperties(saga)); return new SagaDataCorrelationProperties(correlationPropertiesForThisSagaDataType, sagaDataType); }
public RelevantSagaInfo(ISagaData sagaData, IEnumerable <CorrelationProperty> correlationProperties, Saga saga) { SagaData = sagaData; // only keep necessary correlation properties, i.e. CorrelationProperties = correlationProperties .GroupBy(p => p.PropertyName) .Select(g => g.First()) .ToList(); Saga = saga; }
private void StartSaga(IGameMessage @event, Saga saga) { _repository.Add(saga); try { saga.Handle(@event); } finally { CleanUp(saga); } }
public void test_02_first_movements_fails_so_no_rollbacks() { var movements = new List <Movement> { GetFailedMovement(), GetSuccesfullMovement() }; Saga.Start(movements); movements[0].Started.Should().BeTrue(); movements[0].InProcess.Should().BeFalse(); movements[0].IsSuccesfull.Should().BeFalse(); movements[1].IsRollback.Should().BeFalse(); movements[1].Started.Should().BeFalse(); }
public async Task <Saga> CreateAsync(Saga saga, CancellationToken cancellationToken = default) { try { await _sagas.InsertOneAsync(saga, cancellationToken : cancellationToken); } catch (MongoWriteException e) { throw new SagaNotCreatedException(saga.Id.ToString(), e); } return(saga); }
public void Start(object message, Saga saga, Route route) { var adapter = _factory.Create <IMessageAdapter>(_configuration.MessageAdapterType); var interceptor = _factory.Create <IRouterInterceptor>(_configuration.RouterInterceptorType); var context = adapter.Read(message, route.ContentType, route.UseClaimCheck, route.IdentityConfiguration); var when = true; if (route.When != null) { when = route.When(context); } if (when) { interceptor.OnEntry(context); try { var middlewares = new List <Type> { typeof(MessageExceptionHandler) }; middlewares.AddRange(_configuration.InboundMiddlewareTypes); middlewares.AddRange(saga.FirstRoute.MiddlewareTypes); middlewares.Add(typeof(FirstMessageHandler)); context.Route = route; context.Saga = saga; _pipeline.Execute(middlewares.ToArray(), context); interceptor.OnSuccess(context); } catch (Exception ex) { interceptor.OnException(context, ex); throw; } finally { interceptor.OnExit(context); } } }
public UpdateProcessLevyDeclarationsSagaProgressCommandHandlerTestsFixture SetTooManyUpdateAccountTransactionBalancesTasksCompleted() { Saga.Set(s => s.ImportPayeSchemeLevyDeclarationsTasksCompleteCount, AccountPayeSchemes.Count); Tasks = Accounts .Select(a => LevyDeclarationSagaTask.CreateUpdateAccountTransactionBalancesTask(Saga.Id, a.Id)) .Append(LevyDeclarationSagaTask.CreateUpdateAccountTransactionBalancesTask(Saga.Id, Accounts[0].Id)) .ToList(); Db.LevyDeclarationSagaTasks.AddRange(Tasks); Db.SaveChanges(); return(this); }
/// <summary> /// Gets whether a message of the given type is allowed to cause a new saga data instance to be created /// </summary> public bool CanBeInitiatedBy(Type messageType) { // checks if IAmInitiatedBy<TMessage> is implemented by the saga return(CanBeInitiatedByCache .GetOrAdd($"{Handler.GetType().FullName}::{messageType.FullName}", _ => { var implementedInterfaces = Saga.GetType().GetInterfaces(); var handlerTypesToLookFor = new[] { messageType }.Concat(messageType.GetBaseTypes()) .Select(baseType => typeof(IAmInitiatedBy <>).MakeGenericType(baseType)); return implementedInterfaces.Intersect(handlerTypesToLookFor).Any(); })); }
public UpdateProcessLevyDeclarationsSagaProgressCommandHandlerTestsFixture SetSomeUpdateAccountTransactionBalancesTasksCompleted() { Saga.Set(s => s.ImportPayeSchemeLevyDeclarationsTasksCompleteCount, AccountPayeSchemes.Count); Tasks = new List <LevyDeclarationSagaTask> { LevyDeclarationSagaTask.CreateUpdateAccountTransactionBalancesTask(Saga.Id, AccountPayeSchemes[0].AccountId) }; Db.LevyDeclarationSagaTasks.AddRange(Tasks); Db.SaveChanges(); return(this); }
/// <summary> /// Opens the shop /// </summary> /// <param name="character">Character to show the shop</param> /// <param name="basenpc">Npc providing the v</param> public override void Open(Saga.PrimaryTypes.Character character, Saga.Templates.BaseNPC basenpc) { character.Tag = this; SMSG_SHOPLIST spkt = new SMSG_SHOPLIST(); spkt.SessionId = character.id; spkt.SourceActor = basenpc.id; spkt.Zeny = basenpc.Zeny; for (int i = 0; i < list.Count; i++) { ShopPair c = list[i]; if (c.NoStock == true || c.item.count > 0) spkt.AddItem(c.item, c.NoStock, i); } character.client.Send((byte[])spkt); CommonFunctions.SendRebuylist(character); }
internal void RaiseUncorrelatedMessage(object message, Saga saga) { UncorrelatedMessage(message, saga); }
internal void RaiseUncorrelatedMessage(IBus bus, object message, Saga saga) { UncorrelatedMessage(bus, message, saga); }
public override void PostSave(Saga saga, SagaContext context, Exception error) { base.PostSave(null, null, null); PostSaveInvoked = true; }
public override void PreSave(Saga saga, SagaContext context) { }
public RelevantSagaInfo(ISagaData sagaData, IEnumerable<CorrelationProperty> correlationProperties, Saga saga) { SagaData = sagaData; // only keep necessary correlation properties, i.e. CorrelationProperties = correlationProperties .GroupBy(p => p.PropertyName) .Select(g => g.First()) .ToList(); Saga = saga; }
/// <summary> /// Creates a new instance of the saga's saga data /// </summary> public ISagaData CreateNewSagaData(Saga saga) { return saga.CreateNewSagaData(); }
static Dictionary<Type, CorrelationProperty[]> GetCorrelationProperties(Saga saga) { return saga.GenerateCorrelationProperties() .ToLookup(p => p.MessageType) .ToDictionary(kvp => kvp.Key, kvp => kvp.ToArray()); }
IEnumerable<MarketItemArgument> IDatabase.SearchMarket(Saga.Map.Definitions.Misc.MarketSearchArgument Argument) { return SearchMarket(Argument); }
int IDatabase.ExecuteNonQuery(Saga.Data.IQueryProvider query) { return ExecuteNonQuery(query); }
System.Data.IDataReader IDatabase.ExecuteDataReader(Saga.Data.IQueryProvider query) { return ExecuteDataReader(query); }
System.Data.IDataReader IDatabase.ExecuteDataReader(Saga.Data.IQueryProvider query, System.Data.CommandBehavior behavior) { return ExecuteDataReader(query, behavior); }
/// <summary> /// Update an existing saga instance. /// </summary> /// <param name="saga">The saga instance to update.</param> private void UpdateSaga(Saga saga) { var state = serializer.Serialize(saga); var typeId = GetSagaTypeId(saga.GetType()); using (var command = dialect.CreateCommand(dialect.UpdateSaga)) { Log.Trace("Updating existing saga {0}", saga); command.Parameters.Add(dialect.CreateTypeIdParameter(typeId)); command.Parameters.Add(dialect.CreateIdParameter(saga.CorrelationId)); command.Parameters.Add(dialect.CreateVersionParameter(saga.Version)); command.Parameters.Add(dialect.CreateTimeoutParameter(saga.Timeout)); command.Parameters.Add(dialect.CreateStateParameter(state)); if (dialect.ExecuteNonQuery(command) == 0) throw new ConcurrencyException(Exceptions.SagaConcurrencyConflict.FormatWith(saga.GetType(), saga.CorrelationId)); } saga.Version++; }
/// <summary> /// Save the specified <paramref name="context"/> changes for the given <paramref name="saga"/>. /// </summary> /// <param name="saga">The current saga version for which the context applies.</param> /// <param name="context">The saga context containing the saga changes to be applied.</param> public Saga Save(Saga saga, SagaContext context) { Verify.NotNull(saga, nameof(saga)); if (saga.Version == 0 && saga.Completed) return saga; if (saga.Completed) { if (saga.Version > 0) DeleteSaga(saga); } else { if (saga.Version == 0) InsertSaga(saga); else UpdateSaga(saga); } return saga; }
/// <summary> /// Attempt to retrieve an existing saga instance identified by the specified <paramref name="type"/> and <paramref name="id"/>. /// </summary> /// <param name="type">The type of saga to be retrieved.</param> /// <param name="id">The correlation id of the saga to be retrieved.</param> /// <param name="saga">The <see cref="Saga"/> instance if found; otherwise <value>null</value>.</param> public Boolean TryGetSaga(Type type, Guid id, out Saga saga) { Verify.NotNull(type, nameof(type)); using (var command = dialect.CreateCommand(dialect.GetSaga)) { Log.Trace("Getting saga {0} - {1}", type, id); command.Parameters.Add(dialect.CreateIdParameter(id)); command.Parameters.Add(dialect.CreateTypeIdParameter(GetSagaTypeId(type))); saga = dialect.QuerySingle(command, CreateSaga); } return saga != null; }
public override void PostGet(Saga saga) { base.PostGet(null); PostGetInvoked = true; }
protected EventContext CreateEventContext(Saga saga, DateTime timeout) { return new EventContext(saga.CorrelationId, HeaderCollection.Empty, new Timeout(saga.GetType(), timeout)); }
public override void PreSave(Saga saga, SagaContext context) { base.PreSave(null, null); PreSaveInvoked = true; }
/// <summary> /// Delete an existing saga instance. /// </summary> /// <param name="saga">The saga instance to delete.</param> private void DeleteSaga(Saga saga) { var typeId = GetSagaTypeId(saga.GetType()); using (var command = dialect.CreateCommand(dialect.DeleteSaga)) { Log.Trace("Completing existing saga {0}", saga); command.Parameters.Add(dialect.CreateTypeIdParameter(typeId)); command.Parameters.Add(dialect.CreateIdParameter(saga.CorrelationId)); command.Parameters.Add(dialect.CreateVersionParameter(saga.Version)); if (dialect.ExecuteNonQuery(command) == 0) throw new ConcurrencyException(Exceptions.SagaConcurrencyConflict.FormatWith(saga.GetType(), saga.CorrelationId)); } }
public override void PostGet(Saga saga) { }