/// <summary> /// Updates the information on the PlanetLab nodes. /// </summary> /// <param name="state">The manager state.</param> private void OnUpdateNodes(PlManagerState state) { lock (state.Sync) { // Create the list of PlanetLab nodes. List<int> nodes = new List<int>(); foreach (PlNode node in state.Nodes) { nodes.Add(node.Id.Value); } // Raise an event. if (null != this.NodesUpdateStarted) this.NodesUpdateStarted(this, new PlManagerEventArgs(state)); // The asynchronous operation. AsyncWebOperation asyncOperation = new AsyncWebOperation(); // Begin an asynchronous request for the PlanetLab nodes information. asyncOperation = state.BeginAsyncOperation(this.requestGetNodes, this.requestGetNodes.Begin( this.crawler.PlanetLab.Username, this.crawler.PlanetLab.Password, PlNode.GetFilter(PlNode.Fields.NodeId, nodes.ToArray()), (AsyncWebResult result) => { bool success = false; try { // The asynchronous result. AsyncWebResult asyncResult; // Complete the asyncrhonous request. XmlRpcResponse response = this.requestGetNodes.End(result, out asyncResult); // If no fault occurred during the XML-RPC request. if (response.Fault == null) { // Get the response array. XmlRpcArray array = response.Value as XmlRpcArray; // If the array object is not null. if (array != null) { // For each value in the response array. foreach (XmlRpcValue value in array.Values) { // The PlanetLab node. PlNode node = null; // Try parse the structure to a PlanetLab node and add it to the nodes list. try { node = this.crawler.PlanetLab.Nodes.Add(value.Value as XmlRpcStruct); } catch { } } // Raise an event. if (null != this.NodesUpdateFinishedSuccess) this.NodesUpdateFinishedSuccess(this, new PlManagerEventArgs(state)); // Set the success flag to true. success = true; } else { // Raise an event. if (null != this.NodesUpdateFinishedFail) this.NodesUpdateFinishedFail(this, new PlManagerEventArgs(state, "The received response did not contain any PlanetLab node data.")); } } else { // Raise an event. if (null != this.NodesUpdateFinishedFail) this.NodesUpdateFinishedFail(this, new PlManagerEventArgs(state, "{0} (code {1})".FormatWith(response.Fault.FaultString, response.Fault.FaultCode))); } } catch (WebException exception) { // If the exception status is canceled. if (exception.Status == WebExceptionStatus.RequestCanceled) { // Raise an event. if (null != this.NodesUpdateCanceled) this.NodesUpdateCanceled(this, new PlManagerEventArgs(state)); } else { // Raise an event. if (null != this.NodesUpdateFinishedFail) this.NodesUpdateFinishedFail(this, new PlManagerEventArgs(state, exception)); } } catch (Exception exception) { // Raise an event. if (null != this.NodesUpdateFinishedFail) this.NodesUpdateFinishedFail(this, new PlManagerEventArgs(state, exception)); } finally { // End the asynchronous operation. state.EndAsyncOperation(asyncOperation); // If the operation was successful. if (success) { // Execute the commands. this.OnRunNodes(state); } else { // Stop the manager. this.Stop(state); } } })); } }
/// <summary> /// Removes an asynchronous web operation. /// </summary> /// <param name="operation">The asynchronous operation.</param> internal void EndAsyncOperation(AsyncWebOperation operation) { lock (this.sync) { // Remove the operation. this.asyncOperations.Remove(operation); // If the operations list is empty. if (this.asyncOperations.Count == 0) { // Set the wait handle to the signaled state. this.waitAsync.Set(); } } }
/// <summary> /// Removes the result of an asynchronous web operation from the collection of web requests. /// </summary> /// <param name="operation">The asynchronous web operation.</param> public void RemoveAsyncWeb(AsyncWebOperation operation) { lock (this.sync) { // Remove the result. this.asyncWeb.Remove(operation); } }
/// <summary> /// Adds an asynchronous web operation. /// </summary> /// <param name="request">The asynchronous request.</param> /// <param name="result">The asynchronous result.</param> /// <returns>The asynchronous operation.</returns> internal AsyncWebOperation BeginAsyncOperation(AsyncWebRequest request, IAsyncResult result) { // Create the asynchronous web operation. AsyncWebOperation operation = new AsyncWebOperation(request, result); lock (this.sync) { // Verify that the operation does not exist. if (this.asyncOperations.Contains(operation)) throw new InvalidOperationException("Cannot begin an asynchronous operation because the same operation already exists."); // Add the operation to the list. this.asyncOperations.Add(operation); // Set the wait handle to the non-signaled state. this.waitAsync.Reset(); } return operation; }
// Public methods. /// <summary> /// Adds the result of an asynchronous web operation to the collection of web requests. /// </summary> /// <param name="request"></param> /// <param name="result">The result of the web request.</param> public AsyncWebOperation AddAsyncWeb(AsyncWebRequest request, AsyncWebResult result) { // Create the asynchronous web operation. AsyncWebOperation operation = new AsyncWebOperation(request, result); lock (this.sync) { // Add the result. this.asyncWeb.Add(operation); } // Return the web operation. return operation; }