예제 #1
0
        /// <summary>
        /// Attempts the connection.
        /// </summary>
        /// <param name="endpoint">The endpoint.</param>
        /// <param name="workCategoryId">The work category identifier.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>
        /// An awaitable task, the result is the connection result.
        /// </returns>
        protected static async Task <ConnectionResult> AttemptConnection(
            IPEndPoint endpoint,
            int workCategoryId,
            CancellationToken cancellationToken)
        {
            StreamWorkerConnection connection = null;

            try
            {
                var tcpClient = new TcpClient();
                await tcpClient.ConnectAsync(endpoint.Address, endpoint.Port).ConfigureAwait(false);

                connection = new StreamWorkerConnection(tcpClient.GetStream());

                await connection.SendIntAsync(workCategoryId, cancellationToken).ConfigureAwait(false);

                var benchmark = await connection.ReceiveIntAsync(cancellationToken).ConfigureAwait(false);

                // If we've been cancelled, trigger a clean up
                cancellationToken.ThrowIfCancellationRequested();

                return(new ConnectionResult(connection, benchmark));
            }
            catch (Exception ex)
            {
                if (connection != null)
                {
                    connection.Dispose();
                }

                return(new ConnectionResult(ex));
            }
        }
예제 #2
0
        /// <summary>
        /// Processes the client's connection and associated work item asynchronously.
        /// </summary>
        /// <param name="client">The client.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>An awaitable task.</returns>
        private async Task ProcessClientAsync(TcpClient client, CancellationToken cancellationToken)
        {
            IPEndPoint endpoint = null;
            dynamic    workItem = null;

            try
            {
                using (var connection = new StreamWorkerConnection(client.GetStream()))
                {
                    endpoint = (IPEndPoint)client.Client.RemoteEndPoint;

                    // Get our benchmark for the provided work category
                    var workCategoryId = await connection.ReceiveIntAsync(cancellationToken).ConfigureAwait(false);

                    var benchmark = await _workloadBenchmark.GetScoreAsync(workCategoryId).ConfigureAwait(false);

                    // Send the client our benchmark, they'll use this to determine whether to use us for the work
                    await connection.SendIntAsync(benchmark, cancellationToken).ConfigureAwait(false);

                    // Try to receive work from the client, if they close the connection then we'll catch the exception
                    workItem = await connection.ReceiveObjectAsync(cancellationToken).ConfigureAwait(false);

                    // do the work, capturing any exceptions that may occur
                    object    result    = null;
                    Exception exception = null;
                    try
                    {
                        result = await workItem.DoWorkAsync(cancellationToken).ConfigureAwait(false);
                    }
                    catch (Exception ex)
                    {
                        exception = ex;
                    }

                    // Send the client the result of the work item, if an exception occurred, send that instead
                    await connection.SendObjectAsync(exception ?? result, cancellationToken).ConfigureAwait(false);

                    // If an exception occurred while processing work, throw it again to trigger the handling
                    if (exception != null)
                    {
                        throw exception;
                    }
                }
            }
            catch (Exception ex)
            {
                var message = string.Format(
                    "An exception occurred when processing TCP client {0}:{1}.",
                    endpoint != null ? endpoint.Address.ToString() : "????",
                    endpoint != null ? endpoint.Port.ToString(CultureInfo.InvariantCulture) : "????");

                OnWorkException(new WorkException(message, workItem, ex));
            }
        }
예제 #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ConnectionResult"/> struct.
 /// </summary>
 /// <param name="connection">The connection.</param>
 /// <param name="benchmarkScore">The benchmark score.</param>
 public ConnectionResult(StreamWorkerConnection connection, int benchmarkScore)
     : this()
 {
     WorkerConnection = connection;
     CurrentWorkloadBenchmarkScore = benchmarkScore;
 }