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);
            }
        }
Пример #11
0
        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);
            }
        }
Пример #13
0
        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);
        }
Пример #14
0
        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));
            }
        }
Пример #15
0
        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)
            ;
        }
Пример #16
0
        /// <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);
        }