PDA

View Full Version : [CLOSED] Memory leak



bbo1971
May 23, 2012, 7:32 AM
Hi guys we're working on a near real-time monitor using grids and charts with some store.
We also have a TaskManager with a periodic task to reload the store (in our sample every 5 seconds). But after 5/6 hours up and running the browser keeps more than 1 GB of memory and then it crashes. Same behavior in IE, Firefox and chrome.
I slightly modified the Array with Paging grid sample adding a very simple task manager like this



<ext:TaskManager ID="TaskManager1" runat="server">
<Tasks>
<ext:Task AutoRun="true" TaskID="servertime" Interval="1000">
<Listeners>
<Update Handler="#{Store1}.reload();" />
</Listeners>
</ext:Task>
</Tasks>
</ext:TaskManager>


I found the same problem (I changed the refresh interval to amplify the leak effect) in 15 minutes the memory used by Chrome passed from 136.800 to 167.736 Mb. Obviously this is a show stopper bug. Any help?

Daniil
May 23, 2012, 10:38 AM
Hi,

Please follow:
http://forums.ext.net/showthread.php?18647

The problem appears to be stayed in ExtJS 4 as well.

I have found some related ExtJS 4 threads, for example, this one with the opened bug:
http://www.sencha.com/forum/showthread.php?133759

Hope it will be fixed by ExtJS team.

bbo1971
May 23, 2012, 11:00 AM
Hi,
I have found some related ExtJS 4 threads, for example, this one with the opened bug:
http://www.sencha.com/forum/showthread.php?133759

Hope it will be fixed by ExtJS team.
Yep Daniil but the last answer in that thread is dated 26 october 2011. I don't have extjs account can you ask the team? It seems to be a very important bug

Thanks in advance

Vladimir
May 23, 2012, 11:12 AM
At this moment, the single workaround (may be) to reduce aount of rebind.
Is your data changed every 5 sec? Or you rebind always (independ of data changes)?

I suggest to check if data is changed and rebind only if required (another option to change required cells only instead whole data). For example, make ajax request to a server (not reload request), check data on the server, if data is changed then return changed to the server and pass the data to 'loadData' method of the store

If average data changing interval is not 5 sec but 1 min it should seriously improve situation

If real data changing interval is 5 sec but only 2-3 cells are changed then may be to update required cells instead whole data.

If this approaches are interested then i can prepare samples

bbo1971
May 23, 2012, 1:24 PM
Hi Vlad our data are phone calls differently aggregated using some parameters. In our "real" page we have a grid and some charts bound on three different stores. Obviously the simplest way is to reload all the data every 5 or 10 seconds but maybe a "get only changed data" approach should work.
Instead a 1 minute refresh time is absolutely out of question.
I'll really appreciate an example with such approach (we're working on MVC) but saying that I imagine that this bug won't be fixed ever :( and no chances to have it fixed, is it correct?

thanks again
mario

Vladimir
May 23, 2012, 2:08 PM
Instead a 1 minute refresh time is absolutely out of question.

I did not mean to refresh every 1 minute, i meant checking requests every 5 sec and rebind only if data is changed



I imagine that this bug won't be fixed ever :( and no chances to have it fixed, is it correct?

Unfortunatelly, I cannot guarantee that it will be fixed because we are not involved to Sencha developing process. Only Sencha team decides what bugs will be fixed and when. We can report only about issues

bbo1971
May 23, 2012, 2:40 PM
I did not mean to refresh every 1 minute, i meant checking requests every 5 sec and rebind only if data is changed
Yes I understood and I appreciate your help to do this with an example :)



Unfortunatelly, I cannot guarantee that it will be fixed because we are not involved to Sencha developing process. Only Sencha team decides what bugs will be fixed and when. We can report only about issues
I imagine but I hope you have more influence on Sencha dev team to push this bug ;)

I look forward to get your sample over "update only changed cell" example. In your opinion the tremendous memory leak bug is in the store, grid, chart or all of them?
Any hope to have your workaround working ? :)

Daniil
May 23, 2012, 8:23 PM
There are rather many related threads on Sencha forums, so ExtJS team is aware of the problem. Hopefully, they will fix it.


In your opinion the tremendous memory leak bug is in the store, grid, chart or all of them?

Well, analyzing Sencha forums threads I can say that people are commonly facing this problem with grid/store.


I look forward to get your sample over "update only changed cell" example.

We will prepare an example in a few days (probably, today-tomorrow).

Vladimir
May 25, 2012, 1:18 PM
Hi,

Here is samples
1. Update whole data if server side changes are detected
Controller


public ActionResult GetTestData()
{
// emulation of dirty data
// in real project you need to check that data is changed
// if is not chaged need return nothing
// for testing, we return nothing if current scond is even
if(DateTime.Now.Second % 2 == 0)
{
return new AjaxResult();
}


var data = new object[]{
new {Value = DateTime.Now},
new {Value = DateTime.Now.AddHours(1)},
new {Value = DateTime.Now.AddHours(2)},
new {Value = DateTime.Now.AddHours(3)},
new {Value = DateTime.Now.AddHours(4)}
};


return new AjaxResult
{
ExtraParamsResponse = {
new Parameter("data", JSON.Serialize(data), ParameterMode.Raw)
}
};
}


View


<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
<%@ Register Assembly="Ext.Net" TagPrefix="ext" Namespace="Ext.Net" %>


<!DOCTYPE html>


<html>
<head runat="server">
<title></title>


<script type="text/javascript">
function loadData(store, result)
{
var data = result && result.extraParamsResponse && result.extraParamsResponse.data;
if(data)
{
store.loadData(data);
Ext.MessageBox.notify("Data", "Data was changed");
}
else{
Ext.MessageBox.notify("Data", "Data was NOT changed");
}
}
</script>
</head>
<body>
<ext:ResourceManager runat="server" />

<ext:GridPanel
ID="GridPanel1"
runat="server"
Title="Grid">
<Store>
<ext:Store ID="Store1" runat="server" AutoLoad="false">
<Model>
<ext:Model runat="server">
<Fields>
<ext:ModelField Name="Value" Type="Date" />
</Fields>
</ext:Model>
</Model>
</ext:Store>
</Store>
<ColumnModel runat="server">
<Columns>
<ext:DateColumn runat="server" Text="Value" DataIndex="Value" Flex="1" Format="H:mm:ss" />
</Columns>
</ColumnModel>
</ext:GridPanel>


<ext:TaskManager runat="server">
<Tasks>
<ext:Task AutoRun="true" Interval="5000">
<DirectEvents>
<Update Url="/Examples/GetTestData" Success="loadData(#{Store1}, result)" />
</DirectEvents>
</ext:Task>
</Tasks>
</ext:TaskManager>
</body>
</html>







2. Update changed cells only
Controller


public ActionResult GetTestData()
{
return this.Content(JSON.Serialize(new object[]{
new {Value = DateTime.Now},
new {Value = DateTime.Now.AddHours(1)},
new {Value = DateTime.Now.AddHours(2)},
new {Value = DateTime.Now.AddHours(3)},
new {Value = DateTime.Now.AddHours(4)}
}), "application/json");
}


public ActionResult UpdateCells()
{
var store = X.GetCmp<Store>("Store1");

// in real application you have update changed only cells
// for test, we update cell with index 1
store.GetAt(1).Set("Value", DateTime.Now);


return new AjaxResult();
}


View


<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
<%@ Register Assembly="Ext.Net" TagPrefix="ext" Namespace="Ext.Net" %>


<!DOCTYPE html>


<html>
<head runat="server">
<title></title>


<script type="text/javascript">
function loadData(store, result)
{
var data = result && result.extraParamsResponse && result.extraParamsResponse.data;
if(data)
{
store.loadData(data);
Ext.MessageBox.notify("Data", "Data was changed");
}
else{
Ext.MessageBox.notify("Data", "Data was NOT changed");
}
}
</script>
</head>
<body>
<ext:ResourceManager runat="server" />

<ext:GridPanel
ID="GridPanel1"
runat="server"
Title="Grid">
<Store>
<ext:Store ID="Store1" runat="server">
<Model>
<ext:Model runat="server">
<Fields>
<ext:ModelField Name="Value" Type="Date" />
</Fields>
</ext:Model>
</Model>
<Proxy>
<ext:AjaxProxy Url="/Examples/GetTestData">
</ext:AjaxProxy>
</Proxy>
</ext:Store>
</Store>
<ColumnModel runat="server">
<Columns>
<ext:DateColumn runat="server" Text="Value" DataIndex="Value" Flex="1" Format="H:mm:ss" />
</Columns>
</ColumnModel>
</ext:GridPanel>


<ext:TaskManager runat="server">
<Tasks>
<ext:Task AutoRun="true" Interval="5000">
<DirectEvents>
<Update Url="/Examples/UpdateCells" />
</DirectEvents>
</ext:Task>
</Tasks>
</ext:TaskManager>
</body>
</html>

bbo1971
May 25, 2012, 4:18 PM
Thanks a lot Vlad I'll try it in the next week. I'll post the results of my tests and my impression

Bye

drkoh
Jan 25, 2013, 3:38 PM
It is happening to us as well, is there any other work around?

Vladimir
Jan 25, 2013, 3:58 PM
Please see the following posts in this thread
http://forums.ext.net/showthread.php?19142-CLOSED-Memory-leak&p=82525&viewfull=1#post82525
http://forums.ext.net/showthread.php?19142-CLOSED-Memory-leak&p=82758&viewfull=1#post82758

At this moment, it is all what we can suggest

drkoh
Jan 28, 2013, 7:12 PM
Hm.. looks like we are at the mercy of ExtJs... we are using Ext.Net for realtime trading and all records are update every 3 seconds (with ~99% new records). So your suggesstion will not work for us.... I have been checking the Sencha forum and looks like many people reported this and no response from Sencha or what so ever. Is kind of anoying... I wonder is there another way of showing realtime data in Grid without using Store...

Daniil
Jan 29, 2013, 4:47 AM
Maybe this suggestion can help.
http://www.sencha.com/forum/showthread.php?145645&p=910900&viewfull=1#post910900


I wonder is there another way of showing realtime data in Grid without using Store...

I think a Store is an essential part of a GridPanel.

drkoh
Jan 29, 2013, 2:05 PM
Hi Danill,

Just tried that (Put that in the header) and got Ext.util is not define. Then i put it in the body after
<ext:ResourceManager ID="ResourceManager1" runat="server" /> no more complaint. But got error when calling controller, received Request Failure and the response JSON seems fine... not sure why..

drkoh
Jan 29, 2013, 2:28 PM
So, some update. Some how if I set the
Ext.decode = jsonParse;, i got the request failure. I tried just set the
Ext.util.JSON.decode = jsonParse; but leave the
Ext.decode = jsonParse; and the memory leak still exists.

Note: I am testing this in Chrome. One thing tho is I have been testing it using FireFox as well (19.0 Beta Channel) and it seems the memory is cap at <400MB without using the above trick, but Chrome will goes up to ~2GB and crash (shows "Aw Snap" page).

Daniil
Jan 29, 2013, 3:14 PM
The fix seems to really work (though, maybe, more testing needs).

Please see how to apply the fix correctly.

Is there IDProperty setting for the Model on your page? It is required as @sytel says.

Could you try again with your application to confirm it helps or not?

The link to download the json_sans_eval.js (I called it jsonParse.js in my sample):
http://json-sans-eval.googlecode.com/svn/trunk/src/json_sans_eval.js

Example

<%@ Page Language="C#" %>

<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>

<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
if (!X.IsAjaxRequest)
{
this.BindData();
}
}

protected void MyData_Refresh(object sender, StoreReadDataEventArgs e)
{
this.BindData();
}

private void BindData()
{
Store store = this.GridPanel1.GetStore();

store.DataSource = this.Data;
store.DataBind();
}

private object[] Data
{
get
{
DateTime now = DateTime.Now;

return new object[]
{
new object[] { "3m Co", 71.72, 0.02, 0.03, now },
new object[] { "Alcoa Inc", 29.01, 0.42, 1.47, now },
new object[] { "Altria Group Inc", 83.81, 0.28, 0.34, now },
new object[] { "American Express Company", 52.55, 0.01, 0.02, now },
new object[] { "American International Group, Inc.", 64.13, 0.31, 0.49, now },
new object[] { "AT&T Inc.", 31.61, -0.48, -1.54, now },
new object[] { "Boeing Co.", 75.43, 0.53, 0.71, now },
new object[] { "Caterpillar Inc.", 67.27, 0.92, 1.39, now },
new object[] { "Citigroup, Inc.", 49.37, 0.02, 0.04, now },
new object[] { "E.I. du Pont de Nemours and Company", 40.48, 0.51, 1.28, now },
new object[] { "Exxon Mobil Corp", 68.1, -0.43, -0.64, now },
new object[] { "General Electric Company", 34.14, -0.08, -0.23, now },
new object[] { "General Motors Corporation", 30.27, 1.09, 3.74, now },
new object[] { "Hewlett-Packard Co.", 36.53, -0.03, -0.08, now },
new object[] { "Honeywell Intl Inc", 38.77, 0.05, 0.13, now },
new object[] { "Intel Corporation", 19.88, 0.31, 1.58, now },
new object[] { "International Business Machines", 81.41, 0.44, 0.54, now },
new object[] { "Johnson & Johnson", 64.72, 0.06, 0.09, now },
new object[] { "JP Morgan & Chase & Co", 45.73, 0.07, 0.15, now },
new object[] { "McDonald\"s Corporation", 36.76, 0.86, 2.40, now },
new object[] { "Merck & Co., Inc.", 40.96, 0.41, 1.01, now },
new object[] { "Microsoft Corporation", 25.84, 0.14, 0.54, now },
new object[] { "Pfizer Inc", 27.96, 0.4, 1.45, now },
new object[] { "The Coca-Cola Company", 45.07, 0.26, 0.58, now },
new object[] { "The Home Depot, Inc.", 34.64, 0.35, 1.02, now },
new object[] { "The Procter & Gamble Company", 61.91, 0.01, 0.02, now },
new object[] { "United Technologies Corporation", 63.26, 0.55, 0.88, now },
new object[] { "Verizon Communications", 35.57, 0.39, 1.11, now },
new object[] { "Wal-Mart Stores, Inc.", 45.45, 0.73, 1.63, now }
};
}
}
</script>

<!DOCTYPE html>

<html>
<head runat="server">
<title>Simple Array Grid With Paging and Remote Reloading - Ext.NET Examples</title>

<script src="resources/js/jsonParse.js"></script>

<script>
Ext.JSON.decode = jsonParse;
Ext.decode = jsonParse;
</script>

<script>
var template = '<span style="color:{0};">{1}</span>';

var change = function (value) {
return Ext.String.format(template, (value > 0) ? "green" : "red", value);
};

var pctChange = function (value) {
return Ext.String.format(template, (value > 0) ? "green" : "red", value + "%");
};
</script>
</head>
<body>
<form runat="server">
<ext:ResourceManager runat="server" />

<h1>Array Grid with Paging and Remote Reloading</h1>

<p>Demonstrates how to create a grid from Array data with Local Paging and Remote Reloading.</p>

<p>Notice <b>Last Updated</b> column is revised with a new server-side DateTime stamp when the GridPanel "Refresh" button is clicked.<br />This demonstrates that when the GridPanel is refreshed, the Data is requested again from the server via an DirectEvent, but the Paging and Sorting is done completely client-side in the browser.</p>

<ext:TaskManager ID="TaskManager1" runat="server">
<Tasks>
<ext:Task AutoRun="true" TaskID="servertime" Interval="1000">
<Listeners>
<Update Handler="#{Store1}.reload();" />
</Listeners>
</ext:Task>
</Tasks>
</ext:TaskManager>

<ext:GridPanel
ID="GridPanel1"
runat="server"
Title="Array Grid"
Width="700">
<Store>
<ext:Store ID="Store1" runat="server" OnReadData="MyData_Refresh" PageSize="10">
<Model>
<ext:Model runat="server" IDProperty="company">
<Fields>
<ext:ModelField Name="company" />
<ext:ModelField Name="price" Type="Float" />
<ext:ModelField Name="change" Type="Float" />
<ext:ModelField Name="pctChange" Type="Float" />
<ext:ModelField Name="lastChange" Type="Date" />
</Fields>
</ext:Model>
</Model>
</ext:Store>
</Store>
<ColumnModel runat="server">
<Columns>
<ext:RowNumbererColumn runat="server" Width="35" />
<ext:Column runat="server" Text="Company" DataIndex="company" Flex="1" />
<ext:Column runat="server" Text="Price" Width="75" DataIndex="price">
<Renderer Format="UsMoney" />
</ext:Column>
<ext:Column runat="server" Text="Change" Width="75" DataIndex="change">
<Renderer Fn="change" />
</ext:Column>
<ext:Column runat="server" Text="Change" Width="75" DataIndex="pctChange">
<Renderer Fn="pctChange" />
</ext:Column>
<ext:DateColumn runat="server" Text="Last Updated" Width="85" DataIndex="lastChange" Format="H:mm:ss" />
</Columns>
</ColumnModel>
<SelectionModel>
<ext:RowSelectionModel runat="server" Mode="Multi" />
</SelectionModel>
<View>
<ext:GridView runat="server" StripeRows="true">
</ext:GridView>
</View>
<BottomBar>
<ext:PagingToolbar runat="server">
<Items>
<ext:Label runat="server" Text="Page size:" />
<ext:ToolbarSpacer runat="server" Width="10" />
<ext:ComboBox runat="server" Width="80">
<Items>
<ext:ListItem Text="1" />
<ext:ListItem Text="2" />
<ext:ListItem Text="10" />
<ext:ListItem Text="20" />
</Items>
<SelectedItems>
<ext:ListItem Value="10" />
</SelectedItems>
<Listeners>
<Select Handler="#{GridPanel1}.store.pageSize = parseInt(this.getValue(), 10); #{GridPanel1}.store.reload();" />
</Listeners>
</ext:ComboBox>
</Items>
<Plugins>
<ext:ProgressBarPager runat="server" />
</Plugins>
</ext:PagingToolbar>
</BottomBar>
</ext:GridPanel>
</form>
</body>
</html>

drkoh
Jan 29, 2013, 3:35 PM
Hi,

I tried putting the following the
<Head><script src="/Resources/js/json_sans_eval.js" type="text/javascript"></script> <script>
Ext.JSON.decode = jsonParse;
Ext.decode = jsonParse;
</script></head>

and the the Firebug shows
ReferenceError: Ext is not defined
Ext.JSON.decode = jsonParse;

FYI, i am using MVC3


Thanks.

Vladimir
Jan 29, 2013, 3:43 PM
Hi,

Add runat="server" to head tag or you need to place that script after


<ext:ResourcePlaceHolder runat="server" Mode="ScriptFiles" />

drkoh
Jan 29, 2013, 3:56 PM
Hi,

FYI, i am using 1.6 from the branch. (so the Ext version i think is 3.x? and Ext.JSON is in ext 4.x)

Sorry, i think i am almost there.. this is what I have


<head id="Head1" runat="server">
<script src="/Resources/js/jquery-1.4.4.min.js" type="text/javascript"></script>
<script src="/Resources/js/json_sans_eval.js" type="text/javascript"></script>
<ext:ResourcePlaceHolder ID="ResourcePlaceHolder1" runat="server" Mode="ScriptFiles" />
<script>
Ext.JSON.decode = jsonParse;
Ext.decode = jsonParse;
</script>
</head>

and error in FireBug shows the following:


TypeError: Ext.JSON is undefined ==> Ext.JSON.decode = jsonParse;

Daniil
Jan 30, 2013, 3:57 AM
FYI, i am using 1.6 from the branch. (so the Ext version i think is 3.x? and Ext.JSON is in ext 4.x)

Sorry, i think i am almost there.. this is what I have


<head id="Head1" runat="server">
<script src="/Resources/js/jquery-1.4.4.min.js" type="text/javascript"></script>
<script src="/Resources/js/json_sans_eval.js" type="text/javascript"></script>
<ext:ResourcePlaceHolder ID="ResourcePlaceHolder1" runat="server" Mode="ScriptFiles" />
<script>
Ext.JSON.decode = jsonParse;
Ext.decode = jsonParse;
</script>
</head>

and error in FireBug shows the following:


TypeError: Ext.JSON is undefined ==> Ext.JSON.decode = jsonParse;

Well, the current thread is within the 2.x Premium Help forum. So, we expected that you use Ext.NET v2.

For Ext.NET v1 the fix should be:

<head runat="server">
<script src="/Resources/js/json_sans_eval.js" type="text/javascript"></script>

<ext:ResourcePlaceHolder runat="server" Mode="ScriptFiles" />

<script type="text/javascript">
Ext.util.JSON.decode = jsonParse;
Ext.decode = jsonParse;
</script>
</head>

Does it help?

drkoh
Jan 30, 2013, 1:04 PM
Hi Danill,

Ya, i tried the
Ext.util.JSON.decode = jsonParse;
Ext.decode = jsonParse;

and I got the following error when ever store reload the data

5510

But if I only set
Ext.util.JSON.decode = jsonParse; and remove the
Ext.decode = jsonParse; I dont get the above error.

Daniil
Jan 30, 2013, 4:22 PM
I can't rerpoduce. Here is my test case. Could you provide your one?

Example

<%@ Page Language="C#" %>

<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>

<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
if (!X.IsAjaxRequest)
{
this.BindData();
}
}

protected void MyData_Refresh(object sender, StoreRefreshDataEventArgs e)
{
this.BindData();
}

private void BindData()
{
var store = this.GridPanel1.GetStore();

store.DataSource = this.Data;
store.DataBind();
}

private object[] Data
{
get
{
DateTime now = DateTime.Now;

return new object[]
{
new object[] { "3m Co", 71.72, 0.02, 0.03, now },
new object[] { "Alcoa Inc", 29.01, 0.42, 1.47, now },
new object[] { "Altria Group Inc", 83.81, 0.28, 0.34, now },
new object[] { "American Express Company", 52.55, 0.01, 0.02, now },
new object[] { "American International Group, Inc.", 64.13, 0.31, 0.49, now },
new object[] { "AT&T Inc.", 31.61, -0.48, -1.54, now },
new object[] { "Boeing Co.", 75.43, 0.53, 0.71, now },
new object[] { "Caterpillar Inc.", 67.27, 0.92, 1.39, now },
new object[] { "Citigroup, Inc.", 49.37, 0.02, 0.04, now },
new object[] { "E.I. du Pont de Nemours and Company", 40.48, 0.51, 1.28, now },
new object[] { "Exxon Mobil Corp", 68.1, -0.43, -0.64, now },
new object[] { "General Electric Company", 34.14, -0.08, -0.23, now },
new object[] { "General Motors Corporation", 30.27, 1.09, 3.74, now },
new object[] { "Hewlett-Packard Co.", 36.53, -0.03, -0.08, now },
new object[] { "Honeywell Intl Inc", 38.77, 0.05, 0.13, now },
new object[] { "Intel Corporation", 19.88, 0.31, 1.58, now },
new object[] { "International Business Machines", 81.41, 0.44, 0.54, now },
new object[] { "Johnson & Johnson", 64.72, 0.06, 0.09, now },
new object[] { "JP Morgan & Chase & Co", 45.73, 0.07, 0.15, now },
new object[] { "McDonald\"s Corporation", 36.76, 0.86, 2.40, now },
new object[] { "Merck & Co., Inc.", 40.96, 0.41, 1.01, now },
new object[] { "Microsoft Corporation", 25.84, 0.14, 0.54, now },
new object[] { "Pfizer Inc", 27.96, 0.4, 1.45, now },
new object[] { "The Coca-Cola Company", 45.07, 0.26, 0.58, now },
new object[] { "The Home Depot, Inc.", 34.64, 0.35, 1.02, now },
new object[] { "The Procter & Gamble Company", 61.91, 0.01, 0.02, now },
new object[] { "United Technologies Corporation", 63.26, 0.55, 0.88, now },
new object[] { "Verizon Communications", 35.57, 0.39, 1.11, now },
new object[] { "Wal-Mart Stores, Inc.", 45.45, 0.73, 1.63, now }
};
}
}
</script>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Simple Array Grid With Paging and Remote Reloading - Ext.NET Examples</title>

<script src="resources/js/jsonParse.js"></script>

<ext:ResourcePlaceHolder runat="server" Mode="ScriptFiles" />

<script>
Ext.util.JSON.decode = jsonParse;
Ext.decode = jsonParse;
</script>

<script type="text/javascript">
var template = '<span style="color:{0};">{1}</span>';

var change = function (value) {
return String.format(template, (value > 0) ? "green" : "red", value);
};

var pctChange = function (value) {
return String.format(template, (value > 0) ? "green" : "red", value + "%");
};
</script>
</head>
<body>
<form runat="server">
<ext:ResourceManager runat="server" />

<h1>Array Grid with Paging and Remote Reloading</h1>

<p>Demonstrates how to create a grid from Array data with Local Paging and Remote Reloading.</p>

<p>Notice <b>Last Updated</b> column is revised with a new server-side DateTime stamp when the GridPanel "Refresh" button is clicked.<br />This demonstrates that when the GridPanel is refreshed, the Data is requested again from the server via an DirectEvent, but the Paging and Sorting is done completely client-side in the browser.</p>

<ext:TaskManager ID="TaskManager1" runat="server">
<Tasks>
<ext:Task AutoRun="true" TaskID="servertime" Interval="1000">
<Listeners>
<Update Handler="GridPanel1.getStore().reload();" />
</Listeners>
</ext:Task>
</Tasks>
</ext:TaskManager>

<ext:GridPanel
ID="GridPanel1"
runat="server"
StripeRows="true"
Title="Array Grid"
Width="600"
Height="290"
AutoExpandColumn="Company">
<Store>
<ext:Store runat="server" OnRefreshData="MyData_Refresh">
<Reader>
<ext:ArrayReader>
<Fields>
<ext:RecordField Name="company" />
<ext:RecordField Name="price" Type="Float" />
<ext:RecordField Name="change" Type="Float" />
<ext:RecordField Name="pctChange" Type="Float" />
<ext:RecordField Name="lastChange" Type="Date" />
</Fields>
</ext:ArrayReader>
</Reader>
</ext:Store>
</Store>
<ColumnModel runat="server">
<Columns>
<ext:RowNumbererColumn />
<ext:Column ColumnID="Company" Header="Company" Width="160" DataIndex="company" />
<ext:Column Header="Price" Width="75" DataIndex="price">
<Renderer Format="UsMoney" />
</ext:Column>
<ext:Column Header="Change" Width="75" DataIndex="change">
<Renderer Fn="change" />
</ext:Column>
<ext:Column Header="Change" Width="75" DataIndex="pctChange">
<Renderer Fn="pctChange" />
</ext:Column>
<ext:DateColumn Header="Last Updated" Width="85" DataIndex="lastChange" Format="H:mm:ss" />
</Columns>
</ColumnModel>
<SelectionModel>
<ext:RowSelectionModel runat="server" />
</SelectionModel>
<LoadMask ShowMask="true" />
<BottomBar>
<ext:PagingToolbar ID="PagingToolbar1" runat="server" PageSize="10">
<Items>
<ext:Label runat="server" Text="Page size:" />
<ext:ToolbarSpacer runat="server" Width="10" />
<ext:ComboBox runat="server" Width="80">
<Items>
<ext:ListItem Text="1" />
<ext:ListItem Text="2" />
<ext:ListItem Text="10" />
<ext:ListItem Text="20" />
</Items>
<SelectedItem Value="10" />
<Listeners>
<Select Handler="#{PagingToolbar1}.pageSize = parseInt(this.getValue()); #{PagingToolbar1}.doLoad();" />
</Listeners>
</ext:ComboBox>
</Items>
</ext:PagingToolbar>
</BottomBar>
</ext:GridPanel>
</form>
</body>
</html>

Daniil
Feb 05, 2013, 4:23 AM
Hello @drkoh,

Any feedback would be appreciated. Does the fix help or not?

drkoh
Feb 05, 2013, 1:27 PM
Hi sorry for the late response, I still can't get it to work, below is my sample in MVC

View Page

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>

<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>OMS View</title>
<link href="/Resources/css/ui.css" rel="stylesheet" type="text/css" />
<script src="../../Resources/js/jquery-1.4.4.min.js" type="text/javascript"></script>
<script type="text/javascript" src="/Resources/js/site.js"></script>
<script src="/Resources/js/json_sans_eval.js" type="text/javascript"></script>
<ext:ResourcePlaceHolder ID="ResourcePlaceHolder1" runat="server" Mode="ScriptFiles" />
<script>
Ext.util.JSON.decode = jsonParse;
Ext.decode = jsonParse;
</script>
</head>
<body>
<ext:ResourceManager ID="ResourceManager1" runat="server" />
<div id="StoreGroup">
<ext:Store ID="Store_Test" runat="server" ShowWarningOnFailure="true" WarningOnDirty="false" AutoLoad="false" RemoteSort="true">
<Proxy>
<ext:HttpProxy Url="/OMSRead/GetTest/" />
</Proxy>
<Reader>
<ext:JsonReader IDProperty="TestId" Root="data" TotalProperty="total">
<Fields>
<ext:RecordField Name="Test" Type="String" />
</Fields>
</ext:JsonReader>
</Reader>
<BaseParams>
<ext:Parameter Name="start" Value="0" Mode="Raw" />
</BaseParams>
</ext:Store>
</div>
<div id="ContentGroup" style="">
<ext:Viewport ID="Viewport1" runat="server" Layout="BorderLayout">
<Items>
<ext:Panel ID="Panel2" runat="server" Layout="BorderLayout" Region="Center" Border="false" Cls="border-bottom">
<Items>
<ext:GridPanel ID="GridPanel_Test" Region="Center" StripeRows="true" runat="server" StoreID="Store_Test" Border="false" TrackMouseOver="true" Cls="border-right">
<ColumnModel ID="ColumnModel1" runat="server">
<Columns>
<ext:Column DataIndex="Test" Header="Test" Width="100" Hideable="false">
</ext:Column>
</Columns>
</ColumnModel>
<SelectionModel>
<ext:RowSelectionModel ID="RowSelectionModel1" runat="server">
</ext:RowSelectionModel>
</SelectionModel>
<BottomBar>
<ext:PagingToolbar ID="PagingToolbar1" runat="server" PageSize="50">
<Items>
</Items>
</ext:PagingToolbar>
</BottomBar>
</ext:GridPanel>
</Items>
</ext:Panel>
</Items>
</ext:Viewport>
</div>
</body>
</html>




Controller


public AjaxStoreResult GetTest() {
AjaxStoreResult result = new AjaxStoreResult("");
try
{
int total = 1;
string[] d = { "Test" };
var list = from i in d
select new
{
TestId = 1,
Test = "Test"
};
result = new AjaxStoreResult(list, total);
}
catch (Exception ex) { }
return result;
}


And below is the error I got when Load data
5549

Daniil
Feb 06, 2013, 7:34 AM
Thank you for the sample.

The error occurs because of this JSON parser can't work with unquoted properties names. AjaxStoreResult doesn't quote "data" and "total".

We switched it to be quoted in Ext.NET v2, but will leave as it in Ext.NET v1 as it is.

I can suggest to use a JsonResult.

Example

public ActionResult GetTest()
{
return new JsonResult()
{
Data = new
{
data = new
{
TestId = "tesdID",
Test = "test"
},
Total = 1
}
};
}

drkoh
Feb 06, 2013, 1:53 PM
HI Daniil,

If I have a collection of data, how would I manually generate the string for the data member?

thanks.

Daniil
Feb 06, 2013, 2:34 PM
Please try this (pseudo code):


public ActionResult GetTest()
{
return new JsonResult()
{
Data = new
{
data = JSON.Serialize("a collection of data"),
Total = "a collection of data".Count
}
};
}

drkoh
Feb 06, 2013, 5:50 PM
Hi, i tried the following and these are the result


public ActionResult GetTest() {
return new JsonResult()
{
Data = new
{
//Doesn't Works
//data = JSON.Serialize(new[] { new { Test = "aaa", TestId = "1" }, new { Test = "bbb", TestId = "2" } }),

//Works:
//data = new[] { new { Test = "aaa", TestId = "1" }, new { Test = "bbb", TestId = "2" }} ,
Total = 2
}
};
}

Doesn't work If using JSON.Serialize i got

{"data":"[{\"Test\":\"aaa\",\"TestId\":\"1\"},{\"Test\":\"bbb\",\"TestId\":\"2\"}]","Total":2}

and works if using the manual way i got

{"data":[{"Test":"aaa","TestId":"1"},{"Test":"bbb","TestId":"2"}],"Total":2}


Thanks.

Daniil
Feb 07, 2013, 4:40 AM
I was wrong, a JSON.Serialize call is not required. JsonResult serializes itself.

drkoh
Feb 07, 2013, 1:06 PM
Ya, I am running a long test and will post the result.
Thanks Danill for help.

drkoh
Feb 07, 2013, 2:35 PM
So looks like it doesn't fix the memory issue,

Below is the memory footprint after around 1 hour of reload every 3 seconds with around 150 rows.
notice the JavaScript memory column is using 1.5GB. Couple of note i would like to share

1. I have a TaskManager running that will call store.reload every 3 seconds, even if I disable calling the store.reload on the Update event, the JavaScript memory seems keep increasing every second.
2. Every store.reload it adds ~1MB to the JavaScript memory footprint.

5570

Thanks.

drkoh
Feb 07, 2013, 3:07 PM
So looks like it doesn't fix the memory issue,

Below is the memory footprint after around 1 hour of reload every 3 seconds with around 150 rows.
notice the JavaScript memory column is using 1.5GB. Couple of note i would like to share

1. I have a TaskManager running that will call store.reload every 3 seconds, even if I disable calling the store.reload on the Update event, the JavaScript memory seems keep increasing every second.
2. Every store.reload it adds ~1MB to the JavaScript memory footprint.

5570

Thanks.

Daniil
Feb 08, 2013, 4:22 AM
Is there IDProperty of the Store's Reader?


1. I have a TaskManager running that will call store.reload every 3 seconds, even if I disable calling the store.reload on the Update event, the JavaScript memory seems keep increasing every second.

Do you mean that just a TaskManager with a Store causes memory leaking?

drkoh
Feb 08, 2013, 2:15 PM
Hi Danill, yes, it seems like it.

Daniil
Feb 08, 2013, 3:54 PM
Can you estimate a JSON parser fix helps to decrease memory leaking or not?

Can you provide a test case to reproduce memory leaking with a TaskManager without a Store?