Example #1
0
        public void TestRingMasterGetFullSubtree()
        {
            ResetCounts();
            queuedNodes = new ConcurrentQueue <string>();
            var cancellation = new CancellationTokenSource();

            Task.Run(async() =>
            {
                var startFrom = string.Empty;
                while (!cancellation.IsCancellationRequested)
                {
                    var children = await helperClient.GetChildren($"/{rootNodeName}", null, $">:{MaxChildrenCount}:{startFrom}");
                    foreach (var child in children)
                    {
                        queuedNodes.Enqueue($"/{rootNodeName}/{child}/mappings/v4ca");
                        startFrom = child;
                    }

                    if (children.Count < MaxChildrenCount)
                    {
                        break;
                    }
                }
            });

            var rate = TestFlowAsync(
                "Get full sub-tree perf test",
                OperationType.GetFullSubtree,
                GetFullSubtreeThread,
                testCaseSeconds * 4)
                       .GetAwaiter().GetResult();

            cancellation.Cancel();
            log($"get full subtree rate: {rate:G4} /sec");
        }
Example #2
0
        /// <summary>
        /// Enumerates the children of the node at the given path without blocking.
        /// </summary>
        /// <param name="ringMaster">Interface to ringmaster</param>
        /// <param name="path">Node path</param>
        /// <param name="maxChildrenPerRequest">Maximum number of children to retrieve with each GetChildren request</param>
        /// <param name="action">Action to execute for each child</param>
        /// <returns>A <see cref="Task"/> that tracks execution of this method</returns>
        /// <remarks>This method issues multiple GetChildren requests to the given <paramref name="ringMaster"/> if required to enumerate
        /// all the children of the given node. It will invoke the given action for each child</remarks>
        public static async Task ForEachChild(this IRingMasterRequestHandler ringMaster, string path, int maxChildrenPerRequest, Action <string> action)
        {
            string startingChildName = string.Empty;

            while (true)
            {
                IReadOnlyList <string> children = await ringMaster.GetChildren(
                    path,
                    watcher : null,
                    retrievalCondition : string.Format(">:{0}:{1}", maxChildrenPerRequest, startingChildName));

                foreach (var child in children)
                {
                    startingChildName = child;
                    action(child);
                }

                if (children.Count < maxChildrenPerRequest)
                {
                    break;
                }
            }
        }
Example #3
0
        /// <summary>
        /// Recursively deletes all the nodes under the given path.
        /// </summary>
        /// <param name="ringMaster">Interface to RingMaster</param>
        /// <param name="path">Path to recursively delete</param>
        /// <param name="cancellationToken">Token to be observed for cancellation signal</param>
        /// <returns>A <see cref="Task"/> that resolves to the number of nodes deleted</returns>
        public async Task <int> Delete(IRingMasterRequestHandler ringMaster, string path, CancellationToken cancellationToken)
        {
            var recursiveDeleteTimer = Stopwatch.StartNew();
            var pendingNodes         = new Stack <NodeState>();
            var deleteOperations     = new List <Op>();

            this.deletedCount = 0;

            try
            {
                pendingNodes.Push(new NodeState(path));

                while (pendingNodes.Count > 0)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    var currentNode = pendingNodes.Pop();

                    if (!currentNode.AllChildrenProcessed)
                    {
                        IReadOnlyList <string> children = await ringMaster.GetChildren(
                            currentNode.Path,
                            watcher : null,
                            retrievalCondition : string.Format(">:{0}:{1}", this.MaxChildrenEnumerationCount, currentNode.StartingChildName));

                        pendingNodes.Push(new NodeState
                        {
                            Path = currentNode.Path,
                            StartingChildName    = children.Count > 0 ? children[children.Count - 1] : string.Empty,
                            AllChildrenProcessed = children.Count < this.MaxChildrenEnumerationCount,
                        });

                        foreach (var child in children)
                        {
                            string childFullPath = (currentNode.Path == "/") ? $"/{child}" : $"{currentNode.Path}/{child}";
                            pendingNodes.Push(new NodeState(childFullPath));
                        }
                    }
                    else
                    {
                        this.instrumentation?.DeleteQueued(this.deletedCount, currentNode.Path);
                        deleteOperations.Add(Op.Delete(currentNode.Path, version: -1));
                    }

                    if (deleteOperations.Count >= this.MaxDeleteBatchLength)
                    {
                        await this.DeleteMulti(ringMaster, deleteOperations);

                        deleteOperations.Clear();
                    }
                }

                if (deleteOperations.Count > 0)
                {
                    await this.DeleteMulti(ringMaster, deleteOperations);
                }

                this.instrumentation?.RecursiveDeleteSucceeded(this.deletedCount, recursiveDeleteTimer.Elapsed);
                return(this.deletedCount);
            }
            catch
            {
                this.instrumentation?.RecursiveDeleteFailed(this.deletedCount, recursiveDeleteTimer.Elapsed);
                throw;
            }
        }