DataPortal_Update and DataPortal_Insert are slow, DataPortal_Fetch is not

DataPortal_Update and DataPortal_Insert are slow, DataPortal_Fetch is not

Old forum URL: forums.lhotka.net/forums/t/10909.aspx


RobKraft posted on Tuesday, November 22, 2011

We have web application running at about 50 clients.  At only one client, the DataPortal_Update and DataPortal_Insert methods are slow.  The response time is acceptable after IIS is restarted, but as the day goes along the response time becomes to slow.

More specifically, we adding logging to the Save method in our business objects, which invokes the Csla Save method.  At the start of the day the time between the very last line of code priort to .Save; and the very first line of code within DataPortal_Update is less than 1 second.  But by the end of the data that has changed to taking more than 60 seconds.

This problem only affects the calls from .Save to either DataPortal_Update or DataPortal_Insert.  DataPortal_Fetch is never slow.

This problem only affects one of our clients.  This client, like many others clients, is running our 32bit app on W2008 with IIS 7.5.

By adding logging lines at every single line of code we have definitely determined that the slow down occurs after "our" code hands control over to the Csla.save method and before "our" code resumes execution in DataPortal_Update.  All the code runs on the same box; there is no .Net remoting.

Any suggestions about tracking this down are greatly appreciated.

RobKraft replied on Tuesday, November 22, 2011

Forgot to mention that this is Csla 3.8.3.

RockfordLhotka replied on Tuesday, November 22, 2011

The only thing that comes to mind, is that perhaps the serialization consumes a lot of memory, and if this is an older 32 bit machine, maybe it has limited RAM, so the serialization is forcing a bunch of paging at the OS level?

JonnyBee replied on Tuesday, November 22, 2011

Have you tried to set CslaAutoCloneOnUpdate to false in Web.Config?
That would eliminate the extra serialization that occurs within CSLA before the DataPortal_Update/Insert.

Are there other differences in patching/ServicePacks or hardware?

Do you use a separate app server for data access or is everything inline (SimpleDataPortal)?

RobKraft replied on Wednesday, November 23, 2011

Thanks for the replies.  I love this community!

We set the CslaAutoCloneOnUpdate to false today as JonnyBee suggested and the performance problems went away.  I don't consider this to be our "fix" yet though.  I need to determine if we truly want to live without the features that the serialization brings as Rocky mentions in this thread: http://forums.lhotka.net/forums/p/7169/47302.aspx#47302

I also still need to figure out why this is slow at one client.  I suspect that:

a) we are serializing some object or collection that we do not need, and it is a collection that is cached and grows in size during the day

b) this particular client has much more of that data than most, or is adding to it more quickly for some reason than our other clients.

Thanks for your help.  I will post what I find.

JonnyBee replied on Thursday, November 24, 2011

Hi Rob,

I'd recommend to use a memory profiler and invstigate what happens in memory in your app.

Most typically - objects remain in memory because of some event or other object still has a reference to it.

 

RobKraft replied on Monday, December 05, 2011

I'd like to share the cause of our problem and resolution.  One of our base classes had an event in it.  This event caused objects that were 20k to swell to 2MB.  Specifically we have this event:

public new event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
We fixed this problem by adding this attribute to the event definition:
[fieldNonSerialized]
We also wrote a unit test to keep an eye on our object sizes:
		[Test]
		public void TheSizeOfOneModuleShouldNotExceed25000bytes()
		{
			var module = ModuleList.GetByModuleID(3);
 
			long lBuffer = 0;
			using (MemoryStream buffer = new MemoryStream())
			{
				BinaryFormatter formatter = new BinaryFormatter();
				formatter.Serialize(buffer, module);
				lBuffer += buffer.Length;
			}
 
			Assert.That(lBuffer, Is.LessThan(25000));
		}

Copyright (c) Marimer LLC