public void can_serialize_access_to_the_same_entity() { //create an aggregate. var sampleAggregateId = new SampleAggregateId(1); var aggregate = TestAggregateFactory.Create <SampleAggregate, SampleAggregate.State>(new SampleAggregate.State(), sampleAggregateId); aggregate.Create(); _sut.Save(aggregate, new Guid("135E4E5F-3D65-43AC-9D8D-8A8B0EFF8501"), null); NeventStoreExGlobalConfiguration.SetLockThreadSleepCount(100); using (var repo1 = CreateRepository()) using (var repo2 = CreateRepository()) { aggregate = repo1.GetById <SampleAggregate>(sampleAggregateId); aggregate.Touch(); //now create another thread that loads and change the same entity var task = Task <Boolean> .Factory.StartNew(() => { var aggregate2 = repo2.GetById <SampleAggregate>(sampleAggregateId); aggregate2.Touch(); repo2.Save(aggregate2, Guid.NewGuid(), null); return(true); }); Thread.Sleep(100); //Let be sure the other task is started doing something. repo1.Save(aggregate, Guid.NewGuid(), null); //should not throw Assert.IsTrue(task.Result); //inner should not throw. } }
public void Start(DocumentStoreConfiguration config) { _config = config; BuildContainer(config); if (_config.EnableSingleAggregateRepositoryCache) { _logger.InfoFormat("Single Aggregate Repository Cache - ENABLED"); JarvisFrameworkGlobalConfiguration.EnableSingleAggregateRepositoryCache(); } else { _logger.InfoFormat("Single Aggregate Repository Cache - DISABLED"); JarvisFrameworkGlobalConfiguration.DisableSingleAggregateRepositoryCache(); } if (_config.DisableRepositoryLockOnAggregateId) { _logger.InfoFormat("Repository lock on Aggregate Id - DISABLED"); NeventStoreExGlobalConfiguration.DisableRepositoryLockOnAggregateId(); } else { _logger.InfoFormat("Repository lock on Aggregate Id - ENABLED"); NeventStoreExGlobalConfiguration.EnableRepositoryLockOnAggregateId(); } Manager = BuildTenants(_container, config); //Setup database check. foreach (var tenant in _config.TenantSettings) { foreach (var connection in _databaseNames) { #pragma warning disable S1848 // Objects should not be created to be dropped immediately without being used new DatabaseHealthCheck( String.Format("Tenant: {0} [Db:{1}]", tenant.TenantId, connection), tenant.GetConnectionString(connection)); #pragma warning restore S1848 // Objects should not be created to be dropped immediately without being used } } while (!StartupCheck()) { _logger.InfoFormat("Some precondition to start the service are not met. Will retry in 3 seconds!"); Thread.Sleep(3000); } if (RebuildSettings.ShouldRebuild && Environment.UserInteractive) { Console.WriteLine("---> Set Log Level to INFO to speedup rebuild (y/N)?"); var res = Console.ReadLine().Trim().ToLowerInvariant(); if (res == "y") { SetLogLevelTo("INFO"); } } _logger.DebugFormat( "Roles:\n api: {0}\n worker : {1}\n projections: {2}", config.IsApiServer, config.IsWorker, config.IsReadmodelBuilder ); InitializeEverything(config); //Check if container misconfigured _container.CheckConfiguration(); }