public void LoadTestSplitRangeNoLock() { try { ShardMapManager smm = ShardMapManagerFactory.GetSqlShardMapManager( Globals.ShardMapManagerConnectionString, ShardMapManagerLoadPolicy.Lazy); RangeShardMap <int> rsm = smm.GetRangeShardMap <int>(ShardMapManagerLoadTests.s_rangeShardMapName); Assert.IsNotNull(rsm); RangeMapping <int> r1 = this.GetRandomRangeMapping(rsm, 2); if (r1 != null) { int splitPoint = _r.Next((int)(r1.Range.Low.Value) + 1, (int)(r1.Range.High.Value) - 1); Debug.WriteLine("Trying to split range mapping for key range ({0} - {1}) at {2}", r1.Range.Low.Value, r1.Range.High.Value, splitPoint); IReadOnlyList <RangeMapping <int> > rList = rsm.SplitMapping(r1, splitPoint); Assert.AreEqual(2, rList.Count); } } catch (ShardManagementException sme) { Debug.WriteLine("Exception caught: {0}", sme.Message); } }
public void LoadTestRangeMappingDDR() { try { ShardMapManager smm = ShardMapManagerFactory.GetSqlShardMapManager( Globals.ShardMapManagerConnectionString, ShardMapManagerLoadPolicy.Lazy); RangeShardMap <int> rsm = smm.GetRangeShardMap <int>(ShardMapManagerLoadTests.s_rangeShardMapName); Assert.IsNotNull(rsm); RangeMapping <int> r1 = this.GetRandomRangeMapping(rsm); if (r1 != null) { int keyToValidate = _r.Next((int)(r1.Range.Low.Value), (int)(r1.Range.High.Value)); Debug.WriteLine("Trying to validate mapping for key {0}", keyToValidate); // Validate mapping by trying to connect s_retryPolicy.ExecuteAction( () => ValidateImpl( (ShardMap)rsm, keyToValidate)); } } catch (ShardManagementException sme) { Debug.WriteLine("Exception caught: {0}", sme.Message); } }
public void LoadTestDeleteRangeMapping() { try { ShardMapManager smm = ShardMapManagerFactory.GetSqlShardMapManager( Globals.ShardMapManagerConnectionString, ShardMapManagerLoadPolicy.Lazy); RangeShardMap <int> rsm = smm.GetRangeShardMap <int>(ShardMapManagerLoadTests.s_rangeShardMapName); Assert.IsNotNull(rsm); RangeMapping <int> r1 = this.GetRandomRangeMapping(rsm); if (r1 != null) { Debug.WriteLine("Trying to delete mapping for range with low value = {0}", r1.Range.Low); RangeMappingUpdate ru = new RangeMappingUpdate(); ru.Status = MappingStatus.Offline; RangeMapping <int> mappingToDelete = rsm.UpdateMapping(r1, ru); rsm.DeleteMapping(mappingToDelete); } } catch (ShardManagementException sme) { Debug.WriteLine("Exception caught: {0}", sme.Message); } }
public void LoadTestRemoveShardFromRangeShardMap() { try { ShardMapManager smm = ShardMapManagerFactory.GetSqlShardMapManager( Globals.ShardMapManagerConnectionString, ShardMapManagerLoadPolicy.Lazy); RangeShardMap <int> rsm = smm.GetRangeShardMap <int>(ShardMapManagerLoadTests.s_rangeShardMapName); Assert.IsNotNull(rsm); List <Shard> existingShards = rsm.GetShards().ToList(); if (existingShards.Count == 0) { return; } // If there is already a shard marked as offline, chose that one to delete. // This can happend if earlier remove operation was terminated for some reason - ex. killing connections. Shard offlineShard = existingShards.Find(e => e.Status == ShardStatus.Offline); if (offlineShard == null) { offlineShard = existingShards[_r.Next(existingShards.Count)]; // First mark shard as offline so that other test threads will not add new mappings to it. offlineShard = rsm.UpdateShard(offlineShard, new ShardUpdate { Status = ShardStatus.Offline }); } Debug.WriteLine("Trying to remove shard at location {0}", offlineShard.Location); RangeMappingUpdate ru = new RangeMappingUpdate(); ru.Status = MappingStatus.Offline; // Remove all mappings from this shard for given shard map. foreach (RangeMapping <int> rm in rsm.GetMappings(offlineShard)) { RangeMapping <int> mappingToDelete = rsm.UpdateMapping(rm, ru); rsm.DeleteMapping(mappingToDelete); } // get shard object again. Shard deleteShard = rsm.GetShard(offlineShard.Location); // now remove shard. rsm.DeleteShard(deleteShard); Debug.WriteLine("Removed shard at location {0} from shard map {1}", deleteShard.Location, rsm); } catch (ShardManagementException sme) { Debug.WriteLine("Exception caught: {0}", sme.Message); } }
private static void CreateShard(RangeShardMap <int> shardMap, Range <int> rangeForNewShard) { // Create a new shard, or get an existing empty shard (if a previous create partially succeeded). Shard shard = CreateOrGetEmptyShard(shardMap); // Create a mapping to that shard. RangeMapping <int> mappingForNewShard = shardMap.CreateRangeMapping(rangeForNewShard, shard); }
/// <summary> /// Creates a new shard (or uses an existing empty shard), adds it to the shard map, /// and assigns it the specified range if possible. /// </summary> public static void CreateShard(RangeShardMap <int> shardMap, Range <int> rangeForNewShard) { // Create a new shard, or get an existing empty shard (if a previous create partially succeeded). Shard shard = CreateOrGetEmptyShard(shardMap); // Create a mapping to that shard. RangeMapping <int> mappingForNewShard = shardMap.CreateRangeMapping(rangeForNewShard, shard); ConsoleUtils.WriteInfo("Mapped range {0} to shard {1}", mappingForNewShard.Value, shard.Location.Database); }
public void LoadTestMergeRangesWithLock() { try { ShardMapManager smm = ShardMapManagerFactory.GetSqlShardMapManager( Globals.ShardMapManagerConnectionString, ShardMapManagerLoadPolicy.Lazy); RangeShardMap <int> rsm = smm.GetRangeShardMap <int>(ShardMapManagerLoadTests.s_rangeShardMapName); Assert.IsNotNull(rsm); IEnumerable <RangeMapping <int> > existingMappings = rsm.GetMappings(new Range <int>(MinMappingPoint, MaxMappingPoint)); IQueryable <RangeMapping <int> > qr = Queryable.AsQueryable(existingMappings); // Find pair of adjacent mappings. var test = from a in qr join b in qr on new { a.Range.High.Value, a.StoreMapping.StoreShard.Id, a.StoreMapping.Status } equals new { b.Range.Low.Value, b.StoreMapping.StoreShard.Id, b.StoreMapping.Status } select new { a, b }; if (test.Count() > 0) { var t = test.First(); Debug.WriteLine("Trying to merge range mapping for key range ({0} - {1}) and ({2} - {3})", t.a.Range.Low.Value, t.a.Range.High.Value, t.b.Range.Low.Value, t.b.Range.High.Value); MappingLockToken mappingLockTokenLeft = MappingLockToken.Create(); rsm.LockMapping(t.a, mappingLockTokenLeft); MappingLockToken mappingLockTokenRight = MappingLockToken.Create(); rsm.LockMapping(t.b, mappingLockTokenLeft); RangeMapping <int> rMerged = rsm.MergeMappings(t.a, t.b, mappingLockTokenLeft, mappingLockTokenRight); Assert.IsNotNull(rMerged); MappingLockToken storeMappingLockToken = rsm.GetMappingLockOwner(rMerged); Assert.AreEqual(storeMappingLockToken, mappingLockTokenLeft, "Expected merged mapping lock id to equal left mapping id!"); rsm.UnlockMapping(rMerged, storeMappingLockToken); storeMappingLockToken = rsm.GetMappingLockOwner(rMerged); Assert.AreEqual(storeMappingLockToken, MappingLockToken.NoLock, "Expected merged mapping lock id to equal default mapping id after unlock!"); } } catch (ShardManagementException sme) { Debug.WriteLine("Exception caught: {0}", sme.Message); } }
/// <summary> /// Helper function to clean list and range shard maps. /// </summary> private static void CleanShardMapsHelper() { ShardMapManager smm = ShardMapManagerFactory.GetSqlShardMapManager( Globals.ShardMapManagerConnectionString, ShardMapManagerLoadPolicy.Lazy); // Remove all existing mappings from the list shard map. ListShardMap <DateTime> lsm; if (smm.TryGetListShardMap <DateTime>(DateTimeShardMapperTests.s_listShardMapName, out lsm)) { Assert.IsNotNull(lsm); foreach (PointMapping <DateTime> pm in lsm.GetMappings()) { PointMapping <DateTime> pmOffline = lsm.MarkMappingOffline(pm); Assert.IsNotNull(pmOffline); lsm.DeleteMapping(pmOffline); } // Remove all shards from list shard map foreach (Shard s in lsm.GetShards()) { lsm.DeleteShard(s); } } // Remove all existing mappings from the range shard map. RangeShardMap <DateTime> rsm; if (smm.TryGetRangeShardMap <DateTime>(DateTimeShardMapperTests.s_rangeShardMapName, out rsm)) { Assert.IsNotNull(rsm); foreach (RangeMapping <DateTime> rm in rsm.GetMappings()) { MappingLockToken mappingLockToken = rsm.GetMappingLockOwner(rm); rsm.UnlockMapping(rm, mappingLockToken); RangeMapping <DateTime> rmOffline = rsm.MarkMappingOffline(rm); Assert.IsNotNull(rmOffline); rsm.DeleteMapping(rmOffline); } // Remove all shards from range shard map foreach (Shard s in rsm.GetShards()) { rsm.DeleteShard(s); } } }
public void LoadTestAddRangeMapping() { try { ShardMapManager smm = ShardMapManagerFactory.GetSqlShardMapManager( Globals.ShardMapManagerConnectionString, ShardMapManagerLoadPolicy.Lazy); RangeShardMap <int> rsm = smm.GetRangeShardMap <int>(ShardMapManagerLoadTests.s_rangeShardMapName); Assert.IsNotNull(rsm); do { // Chose a random shard to add mapping. Shard s = GetRandomOnlineShardFromShardMap((ShardMap)rsm); if (s == null) { continue; } // generate a random range to add a new range mapping and verify that its not already mapped. int minKey = _r.Next(MinMappingPoint, MaxMappingPoint); int maxKey = minKey + _r.Next(1, MaxRangeMappingSize); maxKey = (maxKey <= MaxMappingPoint) ? maxKey : MaxMappingPoint; IReadOnlyList <RangeMapping <int> > existingMapping = rsm.GetMappings(new Range <int>(minKey, maxKey)); if (existingMapping.Count > 0) { continue; } Debug.WriteLine("Trying to add range mapping for key range ({0} - {1}) to shard location {2}", minKey, maxKey, s.Location); RangeMapping <int> r1 = rsm.CreateRangeMapping(new Range <int>(minKey, maxKey), s); Assert.IsNotNull(r1); // Validate mapping by trying to connect s_retryPolicy.ExecuteAction( () => ValidateImpl( (ShardMap)rsm, minKey)); }while (false); } catch (ShardManagementException sme) { Debug.WriteLine("Exception caught: {0}", sme.Message); } }
public void LoadTestSplitRangeWithLock() { try { ShardMapManager smm = ShardMapManagerFactory.GetSqlShardMapManager( Globals.ShardMapManagerConnectionString, ShardMapManagerLoadPolicy.Lazy); RangeShardMap <int> rsm = smm.GetRangeShardMap <int>(ShardMapManagerLoadTests.s_rangeShardMapName); Assert.IsNotNull(rsm); RangeMapping <int> r1 = this.GetRandomRangeMapping(rsm, 2); if (r1 != null) { int splitPoint = _r.Next((int)(r1.Range.Low.Value) + 1, (int)(r1.Range.High.Value) - 1); Debug.WriteLine("Trying to split range mapping for key range ({0} - {1}) at {2}", r1.Range.Low.Value, r1.Range.High.Value, splitPoint); // Lock the mapping MappingLockToken mappingLockToken = MappingLockToken.Create(); rsm.LockMapping(r1, mappingLockToken); IReadOnlyList <RangeMapping <int> > rList = rsm.SplitMapping(r1, splitPoint, mappingLockToken); Assert.AreEqual(2, rList.Count); foreach (RangeMapping <int> r2 in rList) { Assert.IsNotNull(r2); Assert.AreEqual(mappingLockToken, rsm.GetMappingLockOwner(r2), String.Format("LockOwnerId of mapping: {0} does not match id in store!", r2)); // Unlock each mapping and verify rsm.UnlockMapping(r2, mappingLockToken); Assert.AreEqual(MappingLockToken.NoLock, rsm.GetMappingLockOwner(r2), String.Format("Mapping: {0} not unlocked as expected!", r2)); } } } catch (ShardManagementException sme) { Debug.WriteLine("Exception caught: {0}", sme.Message); } }
private RangeMapping <T> MarkMappingOfflineAndUpdateShard <T>(RangeShardMap <T> map, RangeMapping <T> mapping, Shard newShard) { RangeMapping <T> mappingOffline = map.UpdateMapping( mapping, new RangeMappingUpdate { Status = MappingStatus.Offline }); Assert.IsNotNull(mappingOffline); return(map.UpdateMapping( mappingOffline, new RangeMappingUpdate { Shard = newShard })); }
public void LoadTestMergeRangesNoLock() { try { ShardMapManager smm = ShardMapManagerFactory.GetSqlShardMapManager( Globals.ShardMapManagerConnectionString, ShardMapManagerLoadPolicy.Lazy); RangeShardMap <int> rsm = smm.GetRangeShardMap <int>(ShardMapManagerLoadTests.s_rangeShardMapName); Assert.IsNotNull(rsm); IEnumerable <RangeMapping <int> > existingMappings = rsm.GetMappings(new Range <int>(MinMappingPoint, MaxMappingPoint)); IQueryable <RangeMapping <int> > qr = Queryable.AsQueryable(existingMappings); // find pair of adjacent mappings. var test = from a in qr join b in qr on new { a.Range.High.Value, a.StoreMapping.StoreShard.Id, a.StoreMapping.Status } equals new { b.Range.Low.Value, b.StoreMapping.StoreShard.Id, b.StoreMapping.Status } select new { a, b }; if (test.Count() > 0) { var t = test.First(); Debug.WriteLine("Trying to merge range mapping for key range ({0} - {1}) and ({2} - {3})", t.a.Range.Low.Value, t.a.Range.High.Value, t.b.Range.Low.Value, t.b.Range.High.Value); RangeMapping <int> rMerged = rsm.MergeMappings(t.a, t.b); Assert.IsNotNull(rMerged); } } catch (ShardManagementException sme) { Debug.WriteLine("Exception caught: {0}", sme.Message); } }
public void BasicScenarioRangeShardMaps() { bool success = true; string rangeShardMapName = "MultiTenantShardMap"; try { #region DeployShardMapManager // Deploy shard map manager. ShardMapManagerFactory.CreateSqlShardMapManager( Globals.ShardMapManagerConnectionString, ShardMapManagerCreateMode.ReplaceExisting); #endregion DeployShardMapManager #region GetShardMapManager // Obtain shard map manager. ShardMapManager shardMapManager = ShardMapManagerFactory.GetSqlShardMapManager( Globals.ShardMapManagerConnectionString, ShardMapManagerLoadPolicy.Lazy); #endregion GetShardMapManager #region CreateRangeShardMap // Create a single user per-tenant shard map. RangeShardMap <int> multiTenantShardMap = shardMapManager.CreateRangeShardMap <int>(rangeShardMapName); #endregion CreateRangeShardMap #region CreateShardAndRangeMapping for (int i = 0; i < ScenarioTests.s_multiTenantDBs.Length; i++) { // Create the shard. Shard s = multiTenantShardMap.CreateShard( new ShardLocation( Globals.ShardMapManagerTestsDatasourceName, ScenarioTests.s_multiTenantDBs[i])); // Create the mapping. RangeMapping <int> r = multiTenantShardMap.CreateRangeMapping( new Range <int>(i * 10, (i + 1) * 10), s); } #endregion CreateShardAndRangeMapping #region UpdateMapping // Let's add [50, 60) and map it to same shard as 23 i.e. MultiTenantDB3. RangeMapping <int> mappingFor23 = multiTenantShardMap.GetMappingForKey(23); RangeMapping <int> mappingFor50To60 = multiTenantShardMap.CreateRangeMapping( new Range <int>(50, 60), mappingFor23.Shard); Assert.IsTrue(mappingFor23.Shard.Location.Equals(mappingFor50To60.Shard.Location)); // Move [10, 20) from MultiTenantDB2 to MultiTenantDB1 RangeMapping <int> mappingToUpdate = multiTenantShardMap.GetMappingForKey(10); RangeMapping <int> mappingFor5 = multiTenantShardMap.GetMappingForKey(5); bool updateFailed = false; // Try updating that shard in the mapping without taking it offline first. try { multiTenantShardMap.UpdateMapping( mappingToUpdate, new RangeMappingUpdate { Shard = mappingFor5.Shard }); } catch (ShardManagementException smme) { Assert.AreEqual(smme.ErrorCode, ShardManagementErrorCode.MappingIsNotOffline); updateFailed = true; } Trace.Assert(updateFailed); // Mark mapping offline, update shard location. RangeMapping <int> newMappingFor10To20Offline = MarkMappingOfflineAndUpdateShard <int>( multiTenantShardMap, mappingToUpdate, mappingFor5.Shard); // Verify that update succeeded. Assert.IsTrue(newMappingFor10To20Offline.Shard.Location.Equals(mappingFor5.Shard.Location)); Assert.IsTrue(newMappingFor10To20Offline.Status == MappingStatus.Offline); // Bring the mapping back online. RangeMapping <int> newMappingFor10To20Online = multiTenantShardMap.UpdateMapping( newMappingFor10To20Offline, new RangeMappingUpdate { Status = MappingStatus.Online, }); // Verify that update succeeded. Assert.IsTrue(newMappingFor10To20Online.Status == MappingStatus.Online); #endregion UpdateMapping #region DeleteMapping // Find mapping for [0, 10). RangeMapping <int> mappingToDelete = multiTenantShardMap.GetMappingForKey(5); bool operationFailed = false; // Try to delete mapping while it is online, the delete should fail. try { multiTenantShardMap.DeleteMapping(mappingToDelete); } catch (ShardManagementException smme) { operationFailed = true; Assert.AreEqual(smme.ErrorCode, ShardManagementErrorCode.MappingIsNotOffline); } Trace.Assert(operationFailed); // The mapping must be made offline first before it can be deleted. RangeMappingUpdate ru = new RangeMappingUpdate(); ru.Status = MappingStatus.Offline; mappingToDelete = multiTenantShardMap.UpdateMapping(mappingToDelete, ru); Trace.Assert(mappingToDelete.Status == MappingStatus.Offline); multiTenantShardMap.DeleteMapping(mappingToDelete); // Verify that delete succeeded. try { RangeMapping <int> deletedMapping = multiTenantShardMap.GetMappingForKey(5); } catch (ShardManagementException smme) { Assert.AreEqual(smme.ErrorCode, ShardManagementErrorCode.MappingNotFoundForKey); } #endregion DeleteMapping #region OpenConnection without Validation using (SqlConnection conn = multiTenantShardMap.OpenConnectionForKey( 20, Globals.ShardUserConnectionString, ConnectionOptions.None)) { } #endregion OpenConnection without Validation #region OpenConnection with Validation // Use the stale state of "shardToUpdate" shard & see if validation works. bool validationFailed = false; try { using (SqlConnection conn = multiTenantShardMap.OpenConnection( mappingToDelete, Globals.ShardUserConnectionString, ConnectionOptions.Validate)) { } } catch (ShardManagementException smme) { validationFailed = true; Assert.AreEqual(smme.ErrorCode, ShardManagementErrorCode.MappingDoesNotExist); } Assert.AreEqual(validationFailed, true); #endregion OpenConnection with Validation #region OpenConnection without Validation and Empty Cache // Obtain new shard map manager instance ShardMapManager newShardMapManager = ShardMapManagerFactory.GetSqlShardMapManager( Globals.ShardMapManagerConnectionString, ShardMapManagerLoadPolicy.Lazy); // Get the Range Shard Map RangeShardMap <int> newMultiTenantShardMap = newShardMapManager.GetRangeShardMap <int>(rangeShardMapName); using (SqlConnection conn = newMultiTenantShardMap.OpenConnectionForKey( 20, Globals.ShardUserConnectionString, ConnectionOptions.None)) { } #endregion #region OpenConnection with Validation and Empty Cache // Obtain new shard map manager instance newShardMapManager = ShardMapManagerFactory.GetSqlShardMapManager( Globals.ShardMapManagerConnectionString, ShardMapManagerLoadPolicy.Lazy); // Get the Range Shard Map newMultiTenantShardMap = newShardMapManager.GetRangeShardMap <int>(rangeShardMapName); // Create a new mapping RangeMapping <int> newMappingToDelete = newMultiTenantShardMap.CreateRangeMapping( new Range <int>(70, 80), newMultiTenantShardMap.GetMappingForKey(23).Shard); // Delete the mapping newMappingToDelete = newMultiTenantShardMap.UpdateMapping( newMappingToDelete, new RangeMappingUpdate { Status = MappingStatus.Offline, }); newMultiTenantShardMap.DeleteMapping(newMappingToDelete); // Use the stale state of "shardToUpdate" shard & see if validation works. validationFailed = false; try { using (SqlConnection conn = newMultiTenantShardMap.OpenConnection( newMappingToDelete, Globals.ShardUserConnectionString, ConnectionOptions.Validate)) { } } catch (ShardManagementException smme) { validationFailed = true; Assert.AreEqual(smme.ErrorCode, ShardManagementErrorCode.MappingDoesNotExist); } Assert.AreEqual(validationFailed, true); #endregion #region OpenConnectionAsync without Validation using (SqlConnection conn = multiTenantShardMap.OpenConnectionForKeyAsync( 20, Globals.ShardUserConnectionString, ConnectionOptions.None).Result) { } #endregion #region OpenConnectionAsync with Validation // Use the stale state of "shardToUpdate" shard & see if validation works. validationFailed = false; try { using (SqlConnection conn = multiTenantShardMap.OpenConnectionAsync( mappingToDelete, Globals.ShardUserConnectionString, ConnectionOptions.Validate).Result) { } } catch (AggregateException ex) { ShardManagementException smme = ex.InnerException as ShardManagementException; if (smme != null) { validationFailed = true; Assert.AreEqual(smme.ErrorCode, ShardManagementErrorCode.MappingDoesNotExist); } } Assert.AreEqual(validationFailed, true); #endregion #region OpenConnectionAsync without Validation and Empty Cache // Obtain new shard map manager instance newShardMapManager = ShardMapManagerFactory.GetSqlShardMapManager( Globals.ShardMapManagerConnectionString, ShardMapManagerLoadPolicy.Lazy); // Get the Range Shard Map newMultiTenantShardMap = newShardMapManager.GetRangeShardMap <int>(rangeShardMapName); using (SqlConnection conn = newMultiTenantShardMap.OpenConnectionForKeyAsync( 20, Globals.ShardUserConnectionString, ConnectionOptions.None).Result) { } #endregion #region OpenConnectionAsync with Validation and Empty Cache // Obtain new shard map manager instance newShardMapManager = ShardMapManagerFactory.GetSqlShardMapManager( Globals.ShardMapManagerConnectionString, ShardMapManagerLoadPolicy.Lazy); // Get the Range Shard Map newMultiTenantShardMap = newShardMapManager.GetRangeShardMap <int>(rangeShardMapName); // Create a new mapping newMappingToDelete = newMultiTenantShardMap.CreateRangeMapping( new Range <int>(70, 80), newMultiTenantShardMap.GetMappingForKey(23).Shard); // Delete the mapping newMappingToDelete = newMultiTenantShardMap.UpdateMapping( newMappingToDelete, new RangeMappingUpdate { Status = MappingStatus.Offline, }); newMultiTenantShardMap.DeleteMapping(newMappingToDelete); // Use the stale state of "shardToUpdate" shard & see if validation works. validationFailed = false; try { using (SqlConnection conn = newMultiTenantShardMap.OpenConnectionAsync( newMappingToDelete, Globals.ShardUserConnectionString, ConnectionOptions.Validate).Result) { } } catch (AggregateException ex) { ShardManagementException smme = ex.InnerException as ShardManagementException; if (smme != null) { validationFailed = true; Assert.AreEqual(smme.ErrorCode, ShardManagementErrorCode.MappingDoesNotExist); } } Assert.AreEqual(validationFailed, true); #endregion #region GetMapping // Perform tenant lookup. This will populate the cache. for (int i = 0; i < ScenarioTests.s_multiTenantDBs.Length; i++) { RangeMapping <int> result = shardMapManager .GetRangeShardMap <int>("MultiTenantShardMap") .GetMappingForKey((i + 1) * 10); Trace.WriteLine(result.Shard.Location); if (i == 0) { // Since we moved [10,20) to database 1 earlier. Assert.IsTrue(result.Shard.Location.Database == ScenarioTests.s_multiTenantDBs[0]); } else if (i < 4) { Assert.IsTrue(result.Shard.Location.Database == ScenarioTests.s_multiTenantDBs[i + 1]); } else { Assert.IsTrue(result.Shard.Location.Database == ScenarioTests.s_multiTenantDBs[2]); } } // Perform tenant lookup. This will read from the cache. for (int i = 0; i < ScenarioTests.s_multiTenantDBs.Length; i++) { RangeMapping <int> result = shardMapManager .GetRangeShardMap <int>("MultiTenantShardMap") .GetMappingForKey((i + 1) * 10); Trace.WriteLine(result.Shard.Location); if (i == 0) { // Since we moved [10,20) to database 1 earlier. Assert.IsTrue(result.Shard.Location.Database == ScenarioTests.s_multiTenantDBs[0]); } else if (i < 4) { Assert.IsTrue(result.Shard.Location.Database == ScenarioTests.s_multiTenantDBs[i + 1]); } else { Assert.IsTrue(result.Shard.Location.Database == ScenarioTests.s_multiTenantDBs[2]); } } #endregion GetMapping #region Split/Merge int splitPoint = 55; // Split [50, 60) into [50, 55) and [55, 60) RangeMapping <int> mappingToSplit = multiTenantShardMap.GetMappingForKey(splitPoint); IReadOnlyList <RangeMapping <int> > rangesAfterSplit = multiTenantShardMap.SplitMapping(mappingToSplit, splitPoint); rangesAfterSplit = rangesAfterSplit.OrderBy(nr => nr.Value.Low).ToArray(); // We should get 2 ranges back. Assert.AreEqual(2, rangesAfterSplit.Count); Assert.AreEqual(rangesAfterSplit[0].Value.Low, new Range <int>(50, 55).Low); Assert.AreEqual(rangesAfterSplit[0].Value.High, new Range <int>(50, 55).High); Assert.AreEqual(rangesAfterSplit[1].Value.Low, new Range <int>(55, 60).Low); Assert.AreEqual(rangesAfterSplit[1].Value.High, new Range <int>(55, 60).High); // Split [50, 55) into [50, 52) and [52, 55) IReadOnlyList <RangeMapping <int> > newRangesAfterAdd = multiTenantShardMap.SplitMapping(rangesAfterSplit[0], 52); newRangesAfterAdd = newRangesAfterAdd.OrderBy(nr => nr.Value.Low).ToArray(); // We should get 2 ranges back. Assert.AreEqual(2, newRangesAfterAdd.Count); Assert.AreEqual(newRangesAfterAdd[0].Value.Low, new Range <int>(50, 52).Low); Assert.AreEqual(newRangesAfterAdd[0].Value.High, new Range <int>(50, 52).High); Assert.AreEqual(newRangesAfterAdd[1].Value.Low, new Range <int>(52, 55).Low); Assert.AreEqual(newRangesAfterAdd[1].Value.High, new Range <int>(52, 55).High); // Move [50, 52) to MultiTenantDB1 Shard targetShard = multiTenantShardMap.GetShard(new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, ScenarioTests.s_multiTenantDBs[0])); // Mark mapping offline, update shard location. RangeMapping <int> movedMapping1 = MarkMappingOfflineAndUpdateShard <int>( multiTenantShardMap, newRangesAfterAdd[0], targetShard); // Bring the mapping back online. movedMapping1 = multiTenantShardMap.UpdateMapping( movedMapping1, new RangeMappingUpdate { Status = MappingStatus.Online, }); // Mark mapping offline, update shard location. RangeMapping <int> movedMapping2 = MarkMappingOfflineAndUpdateShard <int>( multiTenantShardMap, newRangesAfterAdd[1], targetShard); // Bring the mapping back online. movedMapping2 = multiTenantShardMap.UpdateMapping( movedMapping2, new RangeMappingUpdate { Status = MappingStatus.Online, }); // Obtain the final moved mapping. RangeMapping <int> finalMovedMapping = multiTenantShardMap.MergeMappings(movedMapping1, movedMapping2); Assert.AreEqual(finalMovedMapping.Value.Low, new Range <int>(50, 55).Low); Assert.AreEqual(finalMovedMapping.Value.High, new Range <int>(50, 55).High); #endregion Split/Merge } catch (ShardManagementException smme) { success = false; Trace.WriteLine(String.Format("Error Category: {0}", smme.ErrorCategory)); Trace.WriteLine(String.Format("Error Code : {0}", smme.ErrorCode)); Trace.WriteLine(String.Format("Error Message : {0}", smme.Message)); if (smme.InnerException != null) { Trace.WriteLine(String.Format("Storage Error Message : {0}", smme.InnerException.Message)); if (smme.InnerException.InnerException != null) { Trace.WriteLine(String.Format("SqlClient Error Message : {0}", smme.InnerException.InnerException.Message)); } } } Assert.IsTrue(success); }
public void TestLockingFixInVersion1_2() { // Get shard map manager ShardMapManager smm = ShardMapManagerFactory.GetSqlShardMapManager( Globals.ShardMapManagerConnectionString, ShardMapManagerLoadPolicy.Lazy); // Upgrade to version 1.1 smm.UpgradeGlobalStore(new Version(1, 1)); // Create a range shard map and add few mappings RangeShardMap <int> rsm = smm.CreateRangeShardMap <int>(ShardMapManagerUpgradeTests.s_shardMapNames[1]); Assert.IsNotNull(rsm); Shard s = rsm.CreateShard(new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, ShardMapManagerUpgradeTests.s_shardedDBs[0])); Assert.IsNotNull(s); RangeMapping <int> m1 = rsm.CreateRangeMapping(new Range <int>(1, 10), s); RangeMapping <int> m2 = rsm.CreateRangeMapping(new Range <int>(10, 20), s); RangeMapping <int> m3 = rsm.CreateRangeMapping(new Range <int>(20, 30), s); // Lock first 2 mappings with same lockownerid and third with a different lock owner id MappingLockToken t1 = MappingLockToken.Create(); MappingLockToken t2 = MappingLockToken.Create(); rsm.LockMapping(m1, t1); rsm.LockMapping(m2, t1); rsm.LockMapping(m3, t2); // now try to unlock using token t2. In store version 1.1 it will unlock all mappings rsm.UnlockMapping(t2); foreach (RangeMapping <int> m in rsm.GetMappings()) { Assert.AreEqual(MappingLockToken.NoLock, rsm.GetMappingLockOwner(m)); } // Now upgrade to version 1.2 and try same scenario above. smm.UpgradeGlobalStore(new Version(1, 2)); rsm.LockMapping(m1, t1); rsm.LockMapping(m2, t1); rsm.LockMapping(m3, t2); // Unlock using token t1. It should just unlock 2 mappings and leave last one locked. rsm.UnlockMapping(t1); Assert.AreEqual(MappingLockToken.NoLock, rsm.GetMappingLockOwner(rsm.GetMappingForKey(5))); Assert.AreEqual(MappingLockToken.NoLock, rsm.GetMappingLockOwner(rsm.GetMappingForKey(15))); Assert.AreEqual(t2, rsm.GetMappingLockOwner(rsm.GetMappingForKey(25))); // Cleanup - Delete all mappings. shard will be removed in test cleanup. rsm.UnlockMapping(t2); RangeMappingUpdate ru = new RangeMappingUpdate(); ru.Status = MappingStatus.Offline; foreach (RangeMapping <int> m in rsm.GetMappings()) { rsm.DeleteMapping(rsm.UpdateMapping(m, ru)); } }
public void initInputControls(IniData data, ref short[] initialResults) { chgContext = new ChangerContext(); resetResults(ref initialResults); //------------------------------------------------ throttleCurveChanger = new MultiRangeChanger( new RangeMapping { minFrom = 0, maxFrom = 255, minTo = 0, maxTo = 255 }, 7, new int[] { // quick and ugly int.Parse(data["THROTTLE"]["t0"]), int.Parse(data["THROTTLE"]["t1"]), int.Parse(data["THROTTLE"]["t2"]), int.Parse(data["THROTTLE"]["t3"]), int.Parse(data["THROTTLE"]["t4"]), int.Parse(data["THROTTLE"]["t5"]), int.Parse(data["THROTTLE"]["t6"]) } ); ThrottleHardLimitChanger = new LimiterChanger(int.Parse(data["SPEED"]["min"]), int.Parse(data["SPEED"]["max"]) ); throttleLimitChanger = new MultiRangeChanger(new[] { new MapRangeChanger(new RangeMapping { minFrom = 0, maxFrom = 127, minTo = ThrottleHardLimitChanger.Min, maxTo = 127 }), new MapRangeChanger(new RangeMapping { minFrom = 128, maxFrom = 255, minTo = 128, maxTo = ThrottleHardLimitChanger.Max }) }); SteerHardLimitChanger = new LimiterChanger(0, 255); brakeChanger = new BrakeChanger(126, int.Parse(data["BRAKE"]["previousMotionThreshold"]), int.Parse(data["BRAKE"]["reversePreviousMotionThreshold"]), int.Parse(data["BRAKE"]["cycles"])); //------------------------------------------------ centrR = new MyRect(0, 0, int.Parse(data["CENTER"]["w"]), int.Parse(data["CENTER"]["h"])); bordrR = new MyRect(int.Parse(data["BORDER"]["x"]), int.Parse(data["BORDER"]["y"]), int.Parse(data["BORDER"]["w"]), int.Parse(data["BORDER"]["h"])); deadZoneR = new MyRect(0, 0, bordrR.w - 2 * int.Parse(data["DEADZONE"]["x"]), bordrR.h - 2 * int.Parse(data["DEADZONE"]["y"])); setArmed(false); // TODO make configurable. Reason: poor quality of cheap gamepads gamepadRangeMapping = new RangeMapping { minFrom = -65535, maxFrom = 65535, minTo = 0, maxTo = 255 }; chgInputSteer = new InputChanger(); chgSteer = chgInputSteer //.Chain(new MapRangeChanger(gamepadRangeMapping)) .Chain(SteerHardLimitChanger) ; chgInputThrottle = new InputChanger(); chgThrottle = chgInputThrottle //.Chain(new MapRangeChanger(gamepadRangeMapping)) .Chain(throttleCurveChanger) .Chain(throttleLimitChanger) .Chain(ThrottleHardLimitChanger) .Chain(new ThrottleStatisticChanger(20)) .Chain(brakeChanger) ; }
/// <summary> /// Old version of Lookup which leads to hitting sql map db per every request /// which slows down the whole performance /// </summary> /// <param name="grainIdentity"></param> /// <returns></returns> private Range <int> Lookup1(GrainIdentity grainIdentity) { RangeMapping <int> rangeMapping = _shardMap.GetMappingForKey(grainIdentity.ShardKey); return(rangeMapping.Value); }