0

I am working on a client - server application written in C# that is built using the Apache THRIFT RPC framework.

We have created several IDL files (.thrift files) with service definitions. These services have been implemented in the server and are being called from the client.

An example of a struct and a service definition in an IDL file is given below

struct ViewColumn {

1: string ColumnProperty,
2: i32 ColWidth,
3: i32 ColPosition,
4: bool ColAscending,
5: i32 ColSortOrder,

}

struct FormView {

   1: i32 ID
   2: string formname
   3: list<ViewColumn> SelectedColumns

}

service FormQueries {

   1: FormView FetchFormView()

}

There are a number of such services defined in the entire application.

In the server the service has been implemented as follows

    Public FormView FetchFormView() {

  return something

}

The configuration of the client and server is as follows

Client 1. TSocket 2 TBinaryprotocol 3. TMultiplexedProtocol

Server 1. TserverSocket 2. Tmultiplexedprocessor 3. TbinaryProtocol

Upon calling the service from the client as follows

var f = Queries.FetchFormView()

we encountered some problems.

  1. FetchFormView() returns null
  2. system.OutOfMemoryException

The stack trace of these errors are provided below

Exception of type 'System.OutOfMemoryException' was thrown.
   at Thrift.Protocol.TBinaryProtocol.ReadStringBody(Int32 size) 
   at Thrift.Protocol.TBinaryProtocol.ReadMessageBegin() 
   at Thrift.Protocol.TProtocolDecorator.ReadMessageBegin() 
   at Queries.recv_FetchFormView()
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

FetchFormView failed: unknown result (result is null)
NOTE: This error occurs with other defined services also
   at Queries.recv_FetchFormView()
   at Queries.Client.FetchFormView()
   at Queries.FetchFormView()
   at System.Windows.Forms.ToolStripDropDownItem.OnDropDownShow(EventArgs e)
   at System.Windows.Forms.ToolStripMenuItem.OnDropDownShow(EventArgs e)
   at System.Windows.Forms.ToolStripDropDownItem.ShowDropDownInternal()
   at System.Windows.Forms.ToolStripDropDownItem.ShowDropDown(Boolean mousePush)
   at System.Windows.Forms.ToolStripMenuItem.OnMouseButtonStateChange(MouseEventArgs e, Boolean isMouseDown)
   at System.Windows.Forms.ToolStripMenuItem.OnMouseDown(MouseEventArgs e)
   at System.Windows.Forms.ToolStripItem.HandleMouseDown(MouseEventArgs e)
   at System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
   at System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
   at System.Windows.Forms.ToolStrip.OnMouseDown(MouseEventArgs mea)
   at System.Windows.Forms.Control.WmMouseDown(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   at System.Windows.Forms.ToolStrip.WndProc(Message& m)
   at System.Windows.Forms.MenuStrip.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

If you have experience in using Apache THRIFT in enterprise level applications, please provide me with insights / solutions / ideas and best approaches.

This is a critical situation. Any help is appreciated.

Thanks a ton in advance

Romi

UPDATE - 26/7/13

I have improvised a solution. I am closing /disposing off and recreating the transport and protocol objects before every service call. This is an inefficient way of connecting with the server but it is working. I am thinking of making each service call asynchronous. Probably that will be a better solution.

Romi24
  • 271
  • 2
  • 7
  • 15

1 Answers1

1

If you are using the TMultiplexedProcessor on the server you must use the TMultiplexedProtocol on the client.

Here is the stack you report:

  • Client 1. TSocket & TBinaryprotocol
  • Server 1. TserverSocket 2. Tmultiplexedprocessor 3. TbinaryProtocol

It should look like this:

  • Client 1. TSocket 2. TBinaryprotocol 3.TMultiplexedProtocol
  • Server 1. TServerSocket 2. TMultiplexedProcessor 3. TBinaryProtocol

On the client something like this:

TTransport trans = new TSocket("localhost", 9090));
TProtocol proto = new TBinaryProtocol(trans);
TMultiplexedProtocol mproto = new TMultiplexedProtocol(proto, "FormQueries");
FormQueries.Client Queries = new FormQueries.Client(mproto);
var f = Queries.FetchFormView()

This assumes the FormQueries service was added to the TMultiplexedProcessor on the server with the "FormQueries" key, this string is the way the server determines which service to call so it must match on the client and server.

codeSF
  • 1,162
  • 9
  • 16
  • Thanks for your reply. All the services have been entered to the TMultiplexedProtocol. I erroneously left this out at the time I created this post. In the meanwhile I have updated the post with an improvised solution. But I am not sure it is the right way to go. – Romi24 Jul 26 '13 at 03:17