Suggestions to avoid certain timeouts and exceptions when using SOA


Avoiding Timeouts


 


In HPC 2008 (V2) SOA, a service call lasts more than 10 minutes will cause the broker closes the connection to the client. This will cause a timeout.


 


Example:


      Assume call durations may be longer than 10 minutes but shorter than 30 minutes.


      My service dll is SimpleService.dll


      My service name is SOATests.SoaSimpleService


      My service contract is SOATests.ISoaSimpleService


 


1.    Client: add the following to the client code.


client.InnerChannel.OperationTimeout = TimeSpan.FromMinutes(30);


 


2.    Service side.


 


Add a <serviceAssembly>.dll.config and deploy it together with the <serviceAssembly>.dll to all nodes.


 


Template:


 






<?xml version=”1.0″ encoding=”utf-8″ ?>


<configuration> 


<system.serviceModel>


    <services>


      <service name=”<ServiceImplName>“>


        <endpoint binding=”netTcpBinding” bindingConfiguration=”ServiceBinding”


          name=”tcpbinging0″ contract=”<ServiceContractName>” />


      </service>


    </services>


    <bindings>


      <netTcpBinding>


        <binding name=”ServiceBindingreceiveTimeout=”00:30:00″ portSharingEnabled=”true”>


          <security mode=”Transport” />


        </binding>


      </netTcpBinding>


    </bindings>


  </system.serviceModel>


</configuration>


 


Example: (file is called SimpleService.dll.config)


 


<?xml version=”1.0″ encoding=”utf-8″ ?>


<configuration>


 


  <system.serviceModel>


    <bindings>


      <netTcpBinding>


        <binding name=”myBinding”  receiveTimeout=”00:30:00″>         


          <security mode=”Transport” />


        </binding>


      </netTcpBinding>


    </bindings>


   


    <services>


      <service name=”SOATests.SoaSimpleService”>       


        <endpoint address=”” binding=”netTcpBinding”


            bindingConfiguration=”myBinding”


            contract=”SOATests.ISoaSimpleService”/>


       


      </service>


    </services>


  </system.serviceModel>


 


</configuration>


 


 



Avoiding Exceptions


 


In HPC 2008 (V2) SOA, a service call that contains a big array (or list, or other type of collections), WCF might throw an exception – Exception:


 



The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter. The InnerException message was ‘Maximum number of items that can be serialized or deserialized in an object graph is ‘65536’. Change the object graph or increase the MaxItemsInObjectGraph quota.’


 


 


Solution:


 


This is because there are some built-in limits in WCF. This can be configured through app.config file. There are 2 config files that need to be changed.


1.       Client side app.config. Find the binding you are using and add attributes like following sample.


 



  <system.serviceModel>


    <behaviors>


      <endpointBehaviors>


        <behavior name=maxitembehavior>


          <dataContractSerializer maxItemsInObjectGraph=6553600/>


        </behavior>


      </endpointBehaviors>


    </behaviors>


   


    <bindings>


      <netTcpBinding>


        <binding name=netTcpBindingConfiguration


                  maxBufferSize=99000000


                  maxReceivedMessageSize=99000000>


          <readerQuotas maxDepth=900000


                         maxStringContentLength=900000


                         maxArrayLength=900000


                     maxBytesPerRead=900000


                     maxNameTableCharCount=900000 />


          <security mode=Transport />


        </binding>


      </netTcpBinding>


    </bindings>


   


    <client>


      <endpoint name =echosvcclient binding =netTcpBinding bindingConfiguration =netTcpBindingConfiguration contract =EchoSvcReference.IEchoSvc behaviorConfiguration=maxitembehavior>


        <identity>


          <dns value=localhost />


        </identity>


      </endpoint>


    </client>


 


  </system.serviceModel>


 


2.       The service assembly app.config (depending on your deployment it could be per Compute node or a file share. It’s called <service_assembly_name>.dll.config). Find the Net.tcp binding you are using and add those attributes. Following is an example:



  <system.serviceModel>


    <behaviors>


      <serviceBehaviors>


        <behavior name=EchoSvc.EchoSvcBehavior>


          <dataContractSerializer maxItemsInObjectGraph=6553600 />


        </behavior>


      </serviceBehaviors>


    </behaviors>


    <bindings>


      <netTcpBinding>


        <binding name=myBinding


                 maxBufferSize=99000000


                 maxReceivedMessageSize=99000000


                 receiveTimeout=00:30:00>


          <readerQuotas maxDepth=900000


                        maxStringContentLength=900000


                        maxArrayLength=900000


                        maxBytesPerRead=900000


                        maxNameTableCharCount=900000 />


          <security mode=Transport />


        </binding>


      </netTcpBinding>


    </bindings>


    <services>


      <service name=EchoSvc.EchoSvc behaviorConfiguration=EchoSvc.EchoSvcBehavior>


        <endpoint address=“” binding=netTcpBinding


            bindingConfiguration=myBinding


            contract=EchoSvc.IEchoSvc/>


      </service>


    </services>


  </system.serviceModel>


 


For both configuration files, the key attribute is maxItemsInObjectGraph. But you also want to make sure the message size settings are adjusted according to the size of the object actually transported as parameter.


And here is how I create the service client from client side to use the client binding configuration and transport a big message:



using (Session session = Session.CreateSession(info))


{


    EchoSvcClient client = new EchoSvcClient(“echosvcclient”, session.EndpointReference);


    Dictionary<string, string> a = new Dictionary<string, string>();


 


    for (int i = 0; i < 17000; i++)


        a.Add(i.ToString(), “abc”);


 


    Dictionary<string, string> b = client.EchoArray(a);


    client.Close();


}


 


Comments (0)