Question

When I put my thrift client reference in a using block I get a TTransportException : "Cannot read, Remote side has closed exception."

//THRIFT IDL
namespace csharp ReferenceData.API

exception EntityDoesNotExistException {
    1: string Key;  
}

service ReferenceDataService {
    bool HelloWorld() throws (1: EntityDoesNotExistException entityDoesNotExistException);
}

namespace Server
{
    public class Service: ReferenceDataService.Iface
    {
        public bool HelloWorld()
        {
            throw new EntityDoesNotExistException(){Key = "TEST KEY"};
        }
    }
}

namespace Server
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                var processor = new ReferenceData.API.ReferenceDataService.Processor(new Service());
                TServerTransport serverTransport = new TServerSocket(9094);
                TServer server = new TThreadedServer(processor, serverTransport);
                Console.WriteLine("Running the Payroll Service on port {0}...", "9094");
                server.Serve();
            }
            catch (Exception x)
            {
               Console.WriteLine(x.StackTrace);
            }

            Console.ReadLine();
        }
    }
}


namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            var transport = new Thrift.Transport.TSocket("127.0.0.1", 9094);
            transport.Open();
            var service = new ReferenceDataService.Client(new Thrift.Protocol.TBinaryProtocol(transport)); 

            using (service)
            {
                try
                {
                    service.HelloWorld();
                }
                catch (EntityDoesNotExistException ex)
                {
                    Console.WriteLine(ex.Key);
                }
            }

            Console.ReadLine();
        }
    }
}

The remote method call actually succeeds but I have observed that the Processor.Process method is called twice and it is the second call that triggers the exception. Should the Process method be called twice? Should I be explicitly calling Dispose like this, I assumed that I should in order to close the socket as soon as possible.

Was it helpful?

Solution

The behaviour is by design.

The Process() method is called until the connection ends, typically because the client disconnects. In that case, ReadMessageBegin() fails with this exception which is expected and caught in TThreadedServer.cs, right below the Process() loop.

For the curious: The exception is thrown in TTransport.ReadAll()

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top