Answered by:
Sync Error: “http request context being aborted by the server”

Question
-
SyncFramework 2.1; WCF; Client is a PC with SqlCe; SQL 2008 with Change Tracking;
My app has been in production without receiving this error for 2 months. Now all the sudden (with no published changes to the service or client) I am getting one of 2 errors when I am trying to create a new SqlCe.sdf file (note: this is only while trying to create a new file … incremental syncs are still working):
“The underlying connection was closed: The connection was closed unexpectedly”
- Or -
“An error occurred while receiving the http response to (http address …) This could be due to the service endpoint binding not using the http protocol. This could also be due to an http request context being aborted by the server (possibly due to the service shutting down).”
(mostly I am getting the 2<sup>nd</sup> error)
I assume the errors started now because the data for the initial sync has grown. I have 50+ tables in the sync, but one table is the culprit … if I limit my sync to include only the one table (which contains 18Mb of data when exported from Sql to a CSV file) and has +200,000 records, the sync fails with the errors above. However, if I limit the select statement to “select top (10) …” it syncs fine. (Note: “select top (100000) …” still fails)
Interestingly, if I limit the sync to include only the 2<sup>nd</sup> largest table (contains 15Mb of data and has 7,500 records) the sync succeeds … it appears to be more of an issue of number of records returned than it does size in Mb.
Client’s app.config (maxed out values are for testing purposes and tried to edit out irrelevant sections):
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="BasicHttpBinding_ILocalDataCacheSyncContract"
closeTimeout="00:02:00" openTimeout="00:05:00" receiveTimeout="00:20:00" sendTimeout="00:05:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false"
messageEncoding="Text" >
<readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647"
maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="SyncServiceLibrary.LocalDataCacheSyncServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="True" />
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
</serviceBehaviors>
</behaviors>
Server’s App.config (maxed out values are for testing purposes tried to edit out irrelevant sections):
<system.serviceModel>
<services>
<service behaviorConfiguration="SyncServiceLibrary.LocalDataCacheSyncServiceBehavior"
name="SyncServiceLibrary.LocalDataCacheSyncService">
<endpoint address=""
binding="wsHttpBinding"
bindingConfiguration="Binding1"
contract="SyncServiceLibrary.ILocalDataCacheSyncContract">
<identity>
<dns value="" />
</identity>
</endpoint>
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/LocalDataCacheSyncService/" />
</baseAddresses>
</host>
</service>
</services>
<system.web>
<compilation debug="false" />
<httpRuntime executionTimeout="600" maxRequestLength="73400" appRequestQueueLimit="300" />
</system.web>
<bindings>
<wsHttpBinding>
<binding name="Binding1"
maxReceivedMessageSize="2147483647"
receiveTimeout="00:20:00" />
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="SyncServiceLibrary.LocalDataCacheSyncServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="True" />
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Friday, May 6, 2011 12:28 PM
Answers
-
I asked WCF forum here: http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/ce7a9654-b8dc-49ac-903c-b7d3cc884aea/
This is what they said:
"Hello, I see you're configuring maxBufferSize with a buffered transfer mode. If the value of this attribute is small, large messages will be dropped. If you increase the value of this attribute, while you will be able to accept large messages, obviously more server memory will be consumed, and if you run out of memory, there's nothing you can do other than increase the physical memory. For large messages, it is recommended to use streamed transfer mode (set transferMode="Streamed" on the binding). This allows the server to start processing the message while the client is still transfering it, rather than wait for the whole message to be transferred, put the whole message in memory, and then process it. However, I'm not sure if Sync Framework supports streamed transfer mode or not."
Does SF support streaming?
- Marked as answer by P H T Tuesday, May 10, 2011 3:54 PM
Monday, May 9, 2011 10:34 PM -
streaming is a WCF feature and independent of Sync Framework. In streaming, the the receiver can start processing the message before its completely delivered. In the case of Sync Framework, it can't process a partially delivered dataset. you can stream the dataset as a file, and as you receive chunks of it, you can write it to a file on the receiver and rehydrate it back to a dataset when you get the entire batch (similar to the way the memory based batching of the SqlSyncProvider works).a
- Marked as answer by P H T Tuesday, May 10, 2011 3:53 PM
Tuesday, May 10, 2011 10:25 AM
All replies
-
are your WCF timeout values long enough to retrieve the 200k rows? you might want to enable WCF tracing so you get the underlying WCF exception.Friday, May 6, 2011 12:37 PM
-
Yes, we have played with timeout values and higher values did not seem to have any impact.
Sorry, forgot to mention ... WCF trace file for error: “An error occurred while receiving the http response to (http address …) This could be due to the service endpoint binding not using the http protocol. This could also be due to an http request context being aborted by the server (possibly due to the service shutting down).” shows the following message:
"Failed to allocate a managed memory buffer of 536870912 bytes. The amount of available memory may be low."
According to the error, it is trying to allocate ~500MB ... the data is around 20Mb.
Please note from the app.config files that we are using a buffered solution.
Friday, May 6, 2011 12:49 PM -
your data size may just show its just 18MB when exported to a CSV but Dataset serialization will bloat that many times over (see: http://blogs.msdn.com/b/mahjayar/archive/2008/10/01/dbsyncprovider-improving-memory-performance-in-wcf-based-synchronization.aspx).
try saving dataset to an xml file or enable message tracing in WCF and you'll see how big it is.
since you're still using the older SqlCeClientSyncProvider/DbServerSyncProvider combo, have you tried enabling batching? or custom dataset serialization?
Friday, May 6, 2011 1:39 PM -
Thanks for the suggestions.
I enabled the trace log for XmlWriterTraceListener and MessageLogging. The message never makes it into the log file so i can't see the actual message to determine its size (is metadata on the size of the message stored in the log file?).
The only information related to the exception I can see is "Exception of type 'System.OutOfMemoryException' was thrown."
Friday, May 6, 2011 3:44 PM -
Hi,
Please try to add <httpRuntime maxRequestLength="" /> with a bigger value such as 25000 in <System.Web> section for both client and server web.config files. Its default value is 4K and may not be enough in some cases.
Thanks,
Dong
This posting is provided AS IS with no warranties, and confers no rights.- Proposed as answer by Dong CaoMicrosoft employee Friday, May 6, 2011 7:16 PM
Friday, May 6, 2011 7:16 PM -
Thanks, yes it is already in the App.config for the server ... i don't have a section for System.Web in the Client file and don't think it makes sense to have it on the client side ... am i wrong?
- Marked as answer by Dong CaoMicrosoft employee Friday, May 6, 2011 9:45 PM
- Unmarked as answer by Dong CaoMicrosoft employee Friday, May 6, 2011 9:45 PM
Friday, May 6, 2011 7:23 PM -
Can you try to add below setting in Service web.config as well:
<binding ... maxBufferSize="[big value]" maxBufferPoolSize="[big value]" ...>
<readerQuotas ... maxStringContentLength="[big value]">
It is a WCF configuration issue. If above settings still do not work for you, you may want to ask WCF forum instead: http://social.msdn.microsoft.com/Forums/en-US/wcf/threads.
Thanks,
Dong
This posting is provided AS IS with no warranties, and confers no rights.Friday, May 6, 2011 10:07 PM -
I already have all of them except the maxBufferSize ... I can't add it because intellisense reports "the maxBufferSize attribute is not declared" ... any idea why (the app.config file is shown in my first post)? Thanks...
Friday, May 6, 2011 10:21 PM -
I only saw <readerQuotas> in your client app.config, but not the server one. Did you copy the up-to-date server app.config?
I don't know why maxBufferSize is not available to you, but you can find it in msdn. Can you try to add it and see if it helps?
Thanks,
Dong
This posting is provided AS IS with no warranties, and confers no rights.Friday, May 6, 2011 10:48 PM -
I asked WCF forum here: http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/ce7a9654-b8dc-49ac-903c-b7d3cc884aea/
This is what they said:
"Hello, I see you're configuring maxBufferSize with a buffered transfer mode. If the value of this attribute is small, large messages will be dropped. If you increase the value of this attribute, while you will be able to accept large messages, obviously more server memory will be consumed, and if you run out of memory, there's nothing you can do other than increase the physical memory. For large messages, it is recommended to use streamed transfer mode (set transferMode="Streamed" on the binding). This allows the server to start processing the message while the client is still transfering it, rather than wait for the whole message to be transferred, put the whole message in memory, and then process it. However, I'm not sure if Sync Framework supports streamed transfer mode or not."
Does SF support streaming?
- Marked as answer by P H T Tuesday, May 10, 2011 3:54 PM
Monday, May 9, 2011 10:34 PM -
streaming is a WCF feature and independent of Sync Framework. In streaming, the the receiver can start processing the message before its completely delivered. In the case of Sync Framework, it can't process a partially delivered dataset. you can stream the dataset as a file, and as you receive chunks of it, you can write it to a file on the receiver and rehydrate it back to a dataset when you get the entire batch (similar to the way the memory based batching of the SqlSyncProvider works).a
- Marked as answer by P H T Tuesday, May 10, 2011 3:53 PM
Tuesday, May 10, 2011 10:25 AM