コード例 #1
0
        /// <summary>
        /// Tests basic ringmaster functionality
        /// </summary>
        /// <param name="ringMaster">RingMaster client</param>
        /// <param name="instanceRootPath">Root path that must be used by this instance for creating nodes</param>
        /// <param name="iteration">Current iteration</param>
        /// <returns><c>true</c> if the functionality test passed, <c>false</c> otherwise</returns>
        private async Task <bool> TestRingMasterFunctionality(IRingMasterRequestHandler ringMaster, string instanceRootPath, long iteration)
        {
            var timer = Stopwatch.StartNew();

            try
            {
                var random = new Random();

                string nodePath = string.Format($"{instanceRootPath}/Node");
                RingMasterWatchdogEventSource.Log.Create(iteration, nodePath);
                await ringMaster.Create(nodePath, null, null, CreateMode.PersistentAllowPathCreation, throwIfNodeExists : false);

                RingMasterWatchdogEventSource.Log.Exists(iteration, nodePath);
                var nodeStat = await ringMaster.Exists(nodePath, watcher : null);

                int    nodeDataLength = random.Next(RingMasterWatchdog.DefaultMaxNodeDataLength);
                byte[] nodeData       = new byte[nodeDataLength];
                random.NextBytes(nodeData);

                RingMasterWatchdogEventSource.Log.SetData(iteration, nodePath, nodeData.Length);
                await ringMaster.SetData(nodePath, nodeData, nodeStat.Version);

                RingMasterWatchdogEventSource.Log.GetData(iteration, nodePath);
                var retrievedData = await ringMaster.GetData(nodePath, watcher : null);

                if (retrievedData == null)
                {
                    RingMasterWatchdogEventSource.Log.GetDataFailed_RetrievedDataIsNull(iteration, nodePath, nodeData.Length);
                    throw new InvalidOperationException($"Node {nodePath}: Retrieved data is null. expectedDataLength={nodeData.Length}");
                }

                if (retrievedData.Length != nodeData.Length)
                {
                    RingMasterWatchdogEventSource.Log.GetDataFailed_RetrievedDataLengthMismatch(iteration, nodePath, nodeData.Length, retrievedData.Length);
                    throw new InvalidOperationException($"Node {nodePath}: Retrieved data length mismatch retrievedDataLength={retrievedData.Length} expectedDataLength={nodeData.Length}");
                }

                if (!retrievedData.SequenceEqual(nodeData))
                {
                    RingMasterWatchdogEventSource.Log.GetDataFailed_RetrievedDataIsDifferent(iteration, nodePath, nodeData.Length);
                    throw new InvalidOperationException($"Node {nodePath}: Retrieved data is different");
                }

                RingMasterWatchdogEventSource.Log.Delete(iteration, nodePath, nodeStat.Version);
                await ringMaster.Delete(nodePath, -1);

                RingMasterWatchdogEventSource.Log.TestRingMasterFunctionalitySucceeded(iteration, timer.ElapsedMilliseconds);
                return(true);
            }
            catch (System.Exception ex)
            {
                RingMasterWatchdogEventSource.Log.TestRingMasterFunctionalityFailed(iteration, timer.ElapsedMilliseconds, ex.ToString());
            }

            return(false);
        }
コード例 #2
0
        /// <summary>
        /// Work load for testing GetNode method
        /// </summary>
        /// <param name="client">RingMasterClient object</param>
        /// <param name="token">Cancellation token</param>
        /// <param name="threadId">Thread sequence number</param>
        /// <returns>Async task</returns>
        private Task GetNodeThread(IRingMasterRequestHandler client, CancellationToken token, int threadId)
        {
            int taskCount = 0;
            var clock     = Stopwatch.StartNew();

            while (!token.IsCancellationRequested)
            {
                while (this.QueuedNodes.TryDequeue(out string path) && !token.IsCancellationRequested)
                {
                    SpinWait.SpinUntil(() => taskCount < this.AsyncTaskCount || token.IsCancellationRequested);
                    var startTime = clock.Elapsed;
                    var task      = client.GetData(path, null)
                                    .ContinueWith(
                        t =>
                    {
                        Interlocked.Decrement(ref taskCount);

                        if (t.Exception != null)
                        {
                            this.IncrementTotalFailures();
                            this.Log($"Failed to get {path}: {t.Exception.Message}");
                        }
                        else
                        {
                            var data = t.Result;
                            this.AddTotalDataSize(data.Length);
                            this.IncrementTotalDataCount();

                            var duration = clock.Elapsed - startTime;
                            MdmHelper.LogOperationDuration((long)duration.TotalMilliseconds, OperationType.Get);
                        }
                    });

                    Interlocked.Increment(ref taskCount);

                    this.QueuedNodes.Enqueue(path);
                }
            }

            SpinWait.SpinUntil(() => taskCount == 0);
            return(Task.FromResult(0));
        }
コード例 #3
0
        /// <summary>
        /// Queries the last applied batch id in the given ringmaster.
        /// </summary>
        /// <param name="ringMaster">An object that can handle ringmaster requests</param>
        /// <returns>The last applied transaction id in the given ringmaster or null if the value cannot be retrieved</returns>
        private static async Task <ulong> QueryRingMasterLastAppliedBatchId(IRingMasterRequestHandler ringMaster)
        {
            byte[] result = await ringMaster.GetData(TestExecutionQueue.LastAppliedBatchIdPath, watcher : null);

            return(BitConverter.ToUInt64(result, 0));
        }
コード例 #4
0
 /// <summary>
 /// Gets the full sub tree under the given path.
 /// </summary>
 /// <param name="ringMaster">Interface to ringmaster</param>
 /// <param name="path">Node path</param>
 /// <param name="withStat">If the stat of the node should be returned</param>
 /// <returns>Task that will resolve on success to the root of the sub tree under the given path</returns>
 public static async Task <TreeNode> GetFullSubtree(this IRingMasterRequestHandler ringMaster, string path, bool withStat = false)
 {
     return(TreeNode.Deserialize(await ringMaster.GetData(PathDecoration.GetFullContentPath(path, withStat), watcher: null)));
 }