Example #1
0
        /// <summary>
        /// Called when the server receives an unserialized request.
        /// </summary>
        /// <param name="requestBytes">The serialized request.</param>
        private void OnRequest(byte[] requestBytes)
        {
            try
            {
                using (var input = new EnhancedMemoryStream(requestBytes))
                {
                    int typeCode = input.ReadInt32();
                    SharedMemMessage request;
                    SharedMemMessage response;

                    if (typeCode < 0)
                    {
                        request = new SharedMemErrorMessage();
                    }
                    else
                    {
                        request = messageFactory.Create(typeCode);
                    }

                    request.InternalReadFrom(input);
                    request.ReadFrom(input);

                    try
                    {
                        response = requestHandler(request);

                        if (response == null)
                        {
                            throw new NullReferenceException("Server request handler returned a NULL response message.");
                        }
                    }
                    catch (Exception e)
                    {
                        response = new SharedMemErrorMessage();
                        response.InternalError = string.Format("{0}: {1}", e.GetType().FullName, e.Message);
                    }

                    response.InternalRequestId   = request.InternalRequestId;
                    response.InternalClientInbox = request.InternalClientInbox;

                    using (var output = new EnhancedMemoryStream(response.SerializedCapacityHint))
                    {
                        output.WriteInt32(response.TypeCode);
                        response.InternalWriteTo(output);
                        response.WriteTo(output);

                        // This call is synchronous but should execute very quickly (microseconds).

                        outbox.Send(response.InternalClientInbox, output.ToArray());
                    }
                }
            }
            catch (Exception e)
            {
                SysLog.LogException(e);
            }
        }
Example #2
0
        /// <summary>
        /// Asynchronously submits a <see cref="SharedMemMessage"/> request message to the server
        /// and waits for and returns the response <see cref="SharedMemMessage"/>.
        /// </summary>
        /// <param name="request">The request message.</param>
        /// <param name="timeout">The optional timeout to override the <see cref="Timeout"/> property.
        /// </param>
        /// <returns>The response <see cref="SharedMemMessage"/>.</returns>
        public Task <SharedMemMessage> CallAsync(SharedMemMessage request, TimeSpan?timeout = null)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            if (request.InternalRequestId != Guid.Empty)
            {
                throw new InvalidOperationException("Cannot reuse a [SharedMemMessage] request instance previously submitted for a call operation.");
            }

            request.InternalRequestId   = Guid.NewGuid();
            request.InternalClientInbox = this.ClientName;

            if (!timeout.HasValue)
            {
                timeout = this.Timeout;
            }

            var operation = new PendingOperation(request, new TaskCompletionSource <SharedMemMessage>(), stopwatch.Elapsed + timeout.Value);

            lock (syncLock)
            {
                pendingOperations.Add(request.InternalRequestId, operation);
            }

            try
            {
                using (var output = new EnhancedMemoryStream(request.SerializedCapacityHint))
                {
                    output.WriteInt32(request.TypeCode);
                    request.InternalWriteTo(output);
                    request.WriteTo(output);

                    // This call is synchronous but should execute very quickly (microseconds).

                    outbox.Send(ServerName, output.ToArray());
                }
            }
            catch (Exception e)
            {
                lock (syncLock)
                {
                    pendingOperations.Remove(operation.RequestMessage.InternalRequestId);
                }

                operation.Tcs.TrySetException(e);
            }

            return(operation.Tcs.Task);
        }