/// <summary> /// Connects to ring master commander. /// </summary> /// <returns>A <see cref="IRingMasterRequestHandler"/> object that represents the connection.</returns> public virtual IRingMasterRequestHandler ConnectToRingMasterCommander() { IRingMasterRequestHandler rm = this.ConnectToRingMaster(); rm.SetAuth(new Id("digest", "commander")).Wait(); return(rm); }
/// <summary> /// Measures the performance of create requests. /// </summary> /// <param name="ringMaster">RingMaster client</param> /// <param name="maxNodes">Number of nodes to create</param> private void CreatePerformanceTest(IRingMasterRequestHandler ringMaster, int maxNodes) { var instrumentation = new CreatePerformanceInstrumentation(); var createPerformanceTest = new CreatePerformance(instrumentation, this.MaxConcurrency, CancellationToken.None); createPerformanceTest.MinChildrenCountPerNode = this.MinChildrenPerNode; createPerformanceTest.MaxChildrenCountPerNode = this.MaxChildrenPerNode; createPerformanceTest.MaxDataSizePerNode = this.MaxDataSize; createPerformanceTest.MinDataSizePerNode = this.MinDataSize; createPerformanceTest.MaxAllowedCodePoint = this.MaxAllowedCodePoint; Trace.TraceInformation($"Create performance test path={this.TestPath}, maxNumberOfNodes={maxNodes}"); var task = Task.Run(() => createPerformanceTest.CreateHierarchy(ringMaster, this.TestPath, this.BatchLength, maxNodes)); long lastSuccessCount = 0; var timer = Stopwatch.StartNew(); while (!task.Wait(5000)) { timer.Stop(); long rate = (long)((instrumentation.Success - lastSuccessCount) * 1000) / timer.ElapsedMilliseconds; Trace.TraceInformation($"Create success={instrumentation.Success}, failure={instrumentation.Failure}, rate={rate}"); timer.Restart(); lastSuccessCount = instrumentation.Success; } }
/// <summary> /// Initializes a new instance of the <see cref="RetriableRingMasterClient" /> class. /// </summary> /// <param name="createClient">The create client function.</param> /// <param name="server">the server</param> /// <param name="vegaServiceInfoReader">The vega service information reader.</param> /// <param name="log">the logger function</param> public RetriableRingMasterClient(Func <string, IRingMasterRequestHandler> createClient, string server, IVegaServiceInfoReader vegaServiceInfoReader = null, Action <string> log = null) { this.createClientFunc = createClient; this.ringMasterRequestHandler = createClient(server); this.vegaServerReader = vegaServiceInfoReader ?? new VegaServiceInfoReader(); this.log = log ?? (s => Trace.TraceInformation(s)); }
/// <summary> /// Create the specified number of nodes nodes directly under the given path. /// </summary> /// <param name="ringMaster">RingMaster client</param> /// <param name="rootPath">Path where the hierarchy must be created</param> /// <param name="batchLength">Number create requests per multi</param> /// <param name="maxNodes">Number of nodes to create</param> public void CreateFlat(IRingMasterRequestHandler ringMaster, string rootPath, int batchLength, int maxNodes) { var random = new RandomGenerator(); int nodesCreated = 0; using (var operationsCompletedEvent = new CountdownEvent(1)) { var operations = new List <Op>(); while (!this.cancellationToken.IsCancellationRequested && nodesCreated < maxNodes) { string childName = random.GetRandomName(this.MinNodeNameLength, this.MaxNodeNameLength); string childPath = (rootPath == "/") ? $"/{childName}" : $"{rootPath}/{childName}"; byte[] childData = random.GetRandomData(this.MinDataSizePerNode, this.MaxDataSizePerNode); operations.Add(Op.Create(childPath, childData, null, CreateMode.Persistent | CreateMode.AllowPathCreationFlag)); nodesCreated++; this.instrumentation?.NodeQueuedForCreate(nodesCreated); if (operations.Count >= batchLength) { this.IssueMultiRequest(ringMaster, operations, operationsCompletedEvent); operations.Clear(); } } if (operations.Count > 0) { this.IssueMultiRequest(ringMaster, operations, operationsCompletedEvent); } operationsCompletedEvent.Signal(); operationsCompletedEvent.Wait(this.cancellationToken); } }
/// <summary> /// Close this request handler. /// </summary> public void Close() { if (this.baseHandler != null) { ManualResetEvent ev = null; if (this.cache != null) { ev = new ManualResetEvent(false); this.onBulkWatcherRemoved = () => { ev.Set(); }; this.SetCacheInstance(null, null, false, true).Wait(); } this.baseHandler.Close(); this.baseHandler = null; if (ev != null) { bool timeout = !ev.WaitOne(15000); if (timeout) { throw new TimeoutException("could not close the Handler in 15 seconds"); } } } }
private async Task IssueRequest(IRingMasterRequestHandler ringMaster, ulong id, string nodePath, CountdownEvent operationsCompletedEvent) { try { string bulkWatcherPath = $"bulkwatcher:{nodePath}"; operationsCompletedEvent.AddCount(); var timer = Stopwatch.StartNew(); var watcher = new Watcher(id, this.instrumentation); var installBulkWatcherRequest = new RequestExists(bulkWatcherPath, watcher); RequestResponse response = await ringMaster.Request(installBulkWatcherRequest); timer.Stop(); if (response.ResultCode == (int)RingMasterException.Code.Ok) { this.instrumentation?.SetWatcherSucceeded(timer.Elapsed); } else { this.instrumentation?.SetWatcherFailed(); } } catch (Exception ex) { Trace.TraceError($"SetBulkWatcher failed id={id}, path={nodePath}, exception={ex.ToString()}"); this.instrumentation?.SetWatcherFailed(); } finally { this.semaphore.Release(); operationsCompletedEvent.Signal(); } }
protected IRingMasterRequestHandler ConnectToRingMaster() { SimpleTransport clientTransport = null; IRingMasterRequestHandler ringMaster = null; bool mustDispose = true; try { var configuration = new RingMasterClient.Configuration(); IRingMasterClientInstrumentation instrumentation = new RingMasterClientInstrumentation(); clientTransport = new SimpleTransport(); ringMaster = new RingMasterClient(configuration, instrumentation, this.protocol, clientTransport, CancellationToken.None); clientTransport.Connect(this.serverTransport); mustDispose = false; return(ringMaster); } finally { if (mustDispose) { ringMaster.Dispose(); clientTransport.Dispose(); } } }
public void SetWatchers(IRingMasterRequestHandler ringMaster) { if (ringMaster == null) { throw new ArgumentNullException(nameof(ringMaster)); } long lastAssignedUniqueId = 0; var random = new RandomGenerator(); Trace.TraceInformation($"Set watchers"); using (var operationsCompletedEvent = new CountdownEvent(1)) { while (!this.cancellationToken.IsCancellationRequested) { var index = random.GetRandomInt(0, this.nodeList.Count); var nodePath = this.nodeList[index]; this.instrumentation?.NodeLoaded(this.nodeList.Count); ulong id = (ulong)Interlocked.Increment(ref lastAssignedUniqueId); this.semaphore.Wait(); Task _ = this.IssueRequest(ringMaster, id, nodePath, operationsCompletedEvent); } operationsCompletedEvent.Signal(); operationsCompletedEvent.Wait(this.cancellationToken); } }
/// <summary> /// Schedule delete for nodes under the given path /// </summary> /// <param name="ringMaster">RingMaster client</param> /// <param name="rootPath">Root path to the nodes</param> public void ScheduledDelete(IRingMasterRequestHandler ringMaster, string rootPath) { if (ringMaster == null) { throw new ArgumentNullException(nameof(ringMaster)); } using (var operationsCompletedEvent = new CountdownEvent(1)) { this.instrumentation?.NodeQueuedForDelete(this.nodeList.Count); string scheduleName = Guid.NewGuid().ToString(); string stagingLocation = $"/$ScheduledDelete/{scheduleName}"; var operations = new List <Op>(); operations.Add(Op.Move(rootPath, -1, stagingLocation, MoveMode.AllowPathCreationFlag)); var scheduledOperations = new Op[1]; scheduledOperations[0] = Op.Delete(stagingLocation, -1, DeleteMode.FastDelete | DeleteMode.CascadeDelete); operations.Add(Op.Run(new RequestMulti(scheduledOperations, completeSynchronously: true, scheduledName: scheduleName))); var timer = Stopwatch.StartNew(); Trace.TraceInformation($"DeletePerformance.ScheduledDelete: rootPath={rootPath}, stagingLocation={stagingLocation}, scheduleName={scheduleName}"); this.IssueMultiRequest(ringMaster, operations, operationsCompletedEvent); operationsCompletedEvent.Signal(); operationsCompletedEvent.Wait(); timer.Stop(); Trace.TraceInformation($"DeletePerformance.ScheduledDelete: scheduleName={scheduleName}, elapsedMilliseconds={timer.ElapsedMilliseconds}"); } }
private void IssueMultiRequest(IRingMasterRequestHandler ringMaster, IReadOnlyList <Op> operations, CountdownEvent operationsCompletedEvent) { var multiRequest = new RequestMulti(operations, completeSynchronously: true, uid: 0); this.semaphore.Wait(); var timer = Stopwatch.StartNew(); int operationsCount = operations.Count; operationsCompletedEvent.AddCount(operationsCount); ringMaster.Request(multiRequest).ContinueWith(responseTask => { this.semaphore.Release(); timer.Stop(); try { RequestResponse response = responseTask.Result; if (response.ResultCode == (int)RingMasterException.Code.Ok) { this.instrumentation?.DeleteMultiSucceeded(operationsCount, timer.Elapsed); } else { this.instrumentation?.DeleteMultiFailed(operationsCount); } } catch (Exception) { this.instrumentation?.DeleteMultiFailed(operationsCount); } finally { operationsCompletedEvent.Signal(operationsCount); } }); }
private async Task SetDataPerformanceTest(IRingMasterRequestHandler ringMasterClient, ConfigurationSection config, CancellationToken cancellationToken) { try { string testRootPath = config.GetStringValue("TestPath"); int maxConcurrentSetDataBatches = config.GetIntValue("MaxConcurrentBatches"); int maxNodes = config.GetIntValue("MaxNodesToLoad"); int batchLength = config.GetIntValue("BatchLength"); ControlPlaneStressServiceEventSource.Log.SetDataPerformanceTestStarted(testRootPath, maxNodes, batchLength); var instrumentation = new SetDataPerformanceInstrumentation(this.MetricsFactory); var setDataPerformanceTest = new SetDataPerformance(instrumentation, maxConcurrentSetDataBatches, cancellationToken); setDataPerformanceTest.MinDataSizePerNode = config.GetIntValue("MinDataSizePerNode"); setDataPerformanceTest.MaxDataSizePerNode = config.GetIntValue("MaxDataSizePerNode"); await setDataPerformanceTest.LoadNodes(ringMasterClient, testRootPath, maxNodes); await Task.Run(() => setDataPerformanceTest.QueueRequests(ringMasterClient, batchLength)); ControlPlaneStressServiceEventSource.Log.SetDataPerformanceTestCompleted(); } catch (Exception ex) { ControlPlaneStressServiceEventSource.Log.SetDataPerformanceTestFailed(ex.ToString()); } }
/// <summary> /// Load the nodes that will be used for this test. /// </summary> /// <param name="ringMaster">RingMaster client</param> /// <param name="rootPath">Root path to the nodes</param> /// <param name="maxNodes">Maximum number of nodes to load</param> /// <param name="maxGetChildrenEnumerationCount">Maximum number of children to enumerate per get children request</param> /// <returns>A <see cref="Task"/> that tracks execution of this method</returns> public async Task LoadNodes(IRingMasterRequestHandler ringMaster, string rootPath, int maxNodes, int maxGetChildrenEnumerationCount = 1000) { Trace.TraceInformation($"LoadNodes rootPath={rootPath}, maxNodes={maxNodes}, maxGetChildrenEnumerationCount={maxGetChildrenEnumerationCount}"); var nodes = new Queue <string>(); nodes.Enqueue(rootPath); while (!this.cancellationToken.IsCancellationRequested && (nodes.Count > 0) && (this.nodeList.Count < maxNodes)) { string currentNode = nodes.Dequeue(); this.nodeList.Add(currentNode); this.instrumentation?.NodeLoaded(this.nodeList.Count); try { await ringMaster.ForEachChild(currentNode, maxGetChildrenEnumerationCount, child => { string childFullPath = (currentNode == "/") ? $"/{child}" : $"{currentNode}/{child}"; nodes.Enqueue(childFullPath); }); } catch (RingMasterException ex) { Trace.TraceError($"Failed to get children of node {currentNode}. Exception={ex}"); } } Trace.TraceInformation($"LoadNodes Completed: {this.nodeList.Count} nodes loaded"); }
/// <summary> /// Work load for ping pong test /// </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 async Task PingPongThread(IRingMasterRequestHandler client, CancellationToken token, int threadId) { var clock = Stopwatch.StartNew(); while (!token.IsCancellationRequested) { try { var startTime = clock.Elapsed; var tasks = Enumerable.Range(0, this.AsyncTaskCount) .Select(task => client.Exists(string.Empty, null, true) .ContinueWith(t => { var duration = clock.Elapsed - startTime; MdmHelper.LogOperationDuration((long)duration.TotalMilliseconds, OperationType.PingPong); })) .ToArray(); await Task.WhenAll(tasks); this.IncrementTotalDataCount(tasks.Length); } catch (Exception ex) { this.IncrementTotalFailures(); this.Log($"Failed to call Batch: {ex.Message}"); } } }
public Task <IRingMasterClientCache> SetCacheInstance(IRingMasterClientCache cache, string cachePrefix, bool auto_invalidate, bool allowReplacement) { RingMasterCachedRequestHandler cachedHandler = null; // we first make sure this.requestHandler is set to a cached handler, but avoiding race conditions on the set. while (true) { IRingMasterRequestHandler currentH = this.requestHandler; cachedHandler = currentH as RingMasterCachedRequestHandler; if (cachedHandler != null) { break; } cachedHandler = new RingMasterCachedRequestHandler(currentH); if (Interlocked.CompareExchange(ref this.requestHandler, cachedHandler, currentH) == currentH) { break; } else { cachedHandler.Abandon(); cachedHandler.Dispose(); cachedHandler = null; } } // then, we call setcacheinstance on the cached handler. Task <IRingMasterClientCache> set = cachedHandler.SetCacheInstance(cache, cachePrefix, auto_invalidate, allowReplacement); return(set); }
/// <summary> /// Synchronizes with the given path. /// </summary> /// <param name="ringMaster">Interface to ringmaster</param> /// <param name="path">Node path</param> /// <returns>Task that tracks the execution of this method</returns> public static async Task Sync(this IRingMasterRequestHandler ringMaster, string path) { RequestResponse response = await ringMaster.Request( new RequestSync( path)); ThrowIfError(response); }
/// <summary> /// Gets the Access Control List associated with a node. /// </summary> /// <param name="ringMaster">Interface to ringmaster</param> /// <param name="path">Node path</param> /// <param name="stat"><see cref="Stat"/> associated with the node</param> /// <returns>Task that will resolve on success to a List of <see cref="Acl"/>s associated /// with the node</returns> public static async Task <IReadOnlyList <Acl> > GetACL(this IRingMasterRequestHandler ringMaster, string path, IStat stat) { RequestResponse response = await ringMaster.Request( new RequestGetAcl(path, stat)); ThrowIfError(response); return((IReadOnlyList <Acl>)response.Content); }
/// <summary> /// Abandons this instance's use of the basehandler, assuming no cache was ever set. /// </summary> public void Abandon() { if (this.cache != null) { throw new InvalidOperationException("cannot abandon an object with a cache"); } this.baseHandler = null; }
private static async Task RegisterBulkWatcherLegacyMethod(IRingMasterRequestHandler ringMaster, string pathPrefix, IWatcher watcher) { string watcherBody = string.Format("$startswith:{0}", pathPrefix); string name = await ringMaster.Create("/$bulkwatcher/watcher", Encoding.UTF8.GetBytes(watcherBody), null, CreateMode.EphemeralSequential); string bulkWatcherPath = string.Format("/$bulkwatcher/{0}", name); await ringMaster.Exists(bulkWatcherPath, watcher); }
/// <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); }
/// <summary> /// Initializes a new instance of the <see cref="RingMasterCachedRequestHandler"/> class. /// </summary> /// <param name="baseHandler">The base handler to use</param> public RingMasterCachedRequestHandler(IRingMasterRequestHandler baseHandler) { if (baseHandler == null) { throw new ArgumentNullException("baseHandler"); } this.onBulkWatcherRemoved = null; this.baseHandler = baseHandler; }
/// <summary> /// Gets the subtree under a given path. /// </summary> /// <param name="ringMaster">Interface to RingMaster.</param> /// <param name="path">The path to get the subtree of.</param> /// <param name="retrievalCondition">Request retrieval condition of the form >:[Top]:[ContinuationPath]</param> /// <param name="options">Request options.</param> /// <returns>Task that will resolve on success to the root of the subtree under the given path.</returns> public static async Task <ResponseGetSubtree> GetSubtree(this IRingMasterRequestHandler ringMaster, string path, string retrievalCondition, RequestGetSubtree.GetSubtreeOptions options = RequestGetSubtree.GetSubtreeOptions.None) { RequestResponse response = await ringMaster.Request(new RequestGetSubtree(path, retrievalCondition, options)); ThrowIfError(response); var treeNodeData = TreeNode.Deserialize((byte[])response.Content); return(new ResponseGetSubtree(treeNodeData, response.ResponsePath)); }
/// <summary> /// Executes multiple operations in a sequence at the server. No atomicity guarantees are provided. /// </summary> /// <param name="ringMaster">Interface to ringmaster</param> /// <param name="operations">List of operations</param> /// <param name="mustCompleteSynchronously">If <c>true</c> the server does not complete the operation /// until all successful operations are guaranteed to be durable (and are applied locally).</param> /// <returns>Task that will resolve on success to a list of /// <see cref="OpResult"/>s</returns> public static async Task <IReadOnlyList <OpResult> > Batch(this IRingMasterRequestHandler ringMaster, IReadOnlyList <Op> operations, bool mustCompleteSynchronously = false) { RequestResponse response = await ringMaster.Request( new RequestBatch( operations, mustCompleteSynchronously)); ThrowIfError(response); return((IReadOnlyList <OpResult>)response.Content); }
private static async Task VerifyBatchOperationAuthFailure(IRingMasterRequestHandler ringMaster, params Op[] operations) { IReadOnlyList <OpResult> results = await ringMaster.Batch(operations); Assert.AreEqual(operations.Length, results.Count); foreach (OpResult result in results) { Assert.AreEqual(RingMasterException.Code.Authfailed, result.ErrCode); } }
/// <summary> /// Sets the client authentication digest /// </summary> /// <param name="ringMaster">Interface to ringmaster</param> /// <param name="clientId">The client id</param> /// <returns>Task that tracks the execution of this method</returns> public static async Task SetAuth(this IRingMasterRequestHandler ringMaster, Id clientId) { string clientIdentity = string.Format( CultureInfo.InvariantCulture, "{0}:{1}", clientId.Scheme, clientId.Identifier); RequestResponse response = await ringMaster.Request(new RequestSetAuth(clientIdentity)); ThrowIfError(response); }
/// <summary> /// Releases unmanaged and - optionally - managed resources. /// </summary> /// <param name="isDisposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> private void Dispose(bool isDisposing) { if (isDisposing) { if (this.baseHandler != null) { this.baseHandler.Dispose(); this.baseHandler = null; } } }
/// <summary> /// Gets the list of children of the node at the given path. /// </summary> /// <param name="ringMaster">Interface to ringmaster</param> /// <param name="path">Node path</param> /// <param name="watcher">Watcher interface that receives notifications for changes to this path or null</param> /// <param name="retrievalCondition">If not null, the retrieval condition in the form >:[top]:[startingChildName]. /// <c> /// ">:[Top]:[ChildName]" ... returns the elements greater than the [ChildName] limited to Top count /// so ">:1000:contoso" means give me first 1000 childrens greater than contoso /// so ">:1000:" means give me first 1000 elements /// </c> /// </param> /// <returns>Task that will resolve on success to the list of names of children of the node</returns> public static async Task <IReadOnlyList <string> > GetChildren(this IRingMasterRequestHandler ringMaster, string path, IWatcher watcher, string retrievalCondition = null) { RequestResponse response = await ringMaster.Request( new RequestGetChildren( path, watcher, retrievalCondition : retrievalCondition)); ThrowIfError(response); return((IReadOnlyList <string>)response.Content); }
/// <summary> /// Sets the access control list for the node at the given path if /// the given version matches the current version of the node. /// </summary> /// <param name="ringMaster">Interface to ringmaster</param> /// <param name="path">Node path</param> /// <param name="acl">Access control list to associate with the node</param> /// <param name="version">Version to compare with the current version of the node</param> /// <returns>Task that will resolve on success to the <see cref="Stat"/> associated with /// the node</returns> public static async Task <IStat> SetACL(this IRingMasterRequestHandler ringMaster, string path, IReadOnlyList <Acl> acl, int version) { RequestResponse response = await ringMaster.Request( new RequestSetAcl( path, acl, version)); ThrowIfError(response); return(response.Stat); }
private async Task CreateAndDeleteHierarchyTest(IRingMasterRequestHandler ringMaster, ConfigurationSection config, CancellationToken cancellationToken) { try { string testPath = config.GetStringValue("CreateAndDeleteHierarchy.TestPath"); int maxNodes = config.GetIntValue("CreateAndDeleteHierarchy.MaxNodes"); bool useScheduledDelete = config.GetBoolValue("CreateAndDeleteHierarchy.UseScheduledDelete"); await ringMaster.Create(testPath, null, null, CreateMode.PersistentAllowPathCreation, throwIfNodeExists : false); while (!cancellationToken.IsCancellationRequested) { var createInstrumentation = new CreatePerformanceInstrumentation(this.MetricsFactory); int maxConcurrentCreateBatches = config.GetIntValue("Create.MaxConcurrentBatches"); int createBatchLength = config.GetIntValue("Create.BatchLength"); var createPerformanceTest = new CreatePerformance(createInstrumentation, maxConcurrentCreateBatches, cancellationToken); createPerformanceTest.MinChildrenCountPerNode = config.GetIntValue("Create.MinChildrenCountPerNode"); createPerformanceTest.MaxChildrenCountPerNode = config.GetIntValue("Create.MaxChildrenCountPerNode"); createPerformanceTest.MinDataSizePerNode = config.GetIntValue("Create.MinDataSizePerNode"); createPerformanceTest.MaxDataSizePerNode = config.GetIntValue("Create.MaxDataSizePerNode"); createPerformanceTest.MaxNodeNameLength = config.GetIntValue("Create.MaxNodeNameLength"); PopulationStressServiceEventSource.Log.CreateAndDeleteHierarchyCreateStarted(testPath, maxNodes, createBatchLength); createPerformanceTest.CreateHierarchy(ringMaster, testPath, createBatchLength, maxNodes); int maxConcurrentDeleteBatches = config.GetIntValue("Delete.MaxConcurrentBatches"); int deleteBatchLength = config.GetIntValue("Delete.BatchLength"); var deleteInstrumentation = new DeletePerformanceInstrumentation(this.MetricsFactory); var deletePerformanceTest = new DeletePerformance(deleteInstrumentation, maxConcurrentDeleteBatches, cancellationToken); PopulationStressServiceEventSource.Log.CreateAndDeleteHierarchyDeleteStarted(testPath, maxNodes, deleteBatchLength, useScheduledDelete); if (useScheduledDelete) { deletePerformanceTest.ScheduledDelete(ringMaster, testPath); } else { await deletePerformanceTest.LoadNodes(ringMaster, testPath, maxNodes); deletePerformanceTest.QueueDeletes(ringMaster, deleteBatchLength); } } PopulationStressServiceEventSource.Log.CreateAndDeleteHierarchyTestCompleted(); } catch (Exception ex) { PopulationStressServiceEventSource.Log.CreateAndDeleteHierarchyTestFailed(ex.ToString()); } }
/// <summary> /// Moves a node with the given path. /// </summary> /// <param name="ringMaster">The ringmaster handler to operate on</param> /// <param name="pathSrc">Node Path to move</param> /// <param name="version">Version of the source node</param> /// <param name="pathDst">Node Path to be parent of the moved node</param> /// <param name="moveMode">Modifiers for the move operation</param> /// <returns>Task that will resolve on success to the path to the newly created node</returns> public static async Task <string> Move(this IRingMasterRequestHandler ringMaster, string pathSrc, int version, string pathDst, MoveMode moveMode) { RequestResponse response = await ringMaster.Request( new RequestMove( pathSrc, version, pathDst, moveMode)); ThrowIfError(response); return((string)response.Content); }
private void GetChildrenPerformanceTest(IRingMasterRequestHandler ringMaster, ConfigurationSection config, CancellationToken cancellationToken) { string testPath = config.GetStringValue("TestPath"); int maxChildren = config.GetIntValue("MaxChildren"); int maxConcurrentRequests = config.GetIntValue("MaxConcurrentRequests"); var instrumentation = new GetChildrenPerformanceInstrumentation(this.MetricsFactory); var getChildrenPerformanceTest = new GetChildrenPerformance(instrumentation, maxConcurrentRequests, cancellationToken); EnumerationStressServiceEventSource.Log.GetChildrenPerformanceTestStarted(testPath, maxChildren, maxConcurrentRequests); getChildrenPerformanceTest.QueueRequests(ringMaster, testPath, maxChildren); }