Showing posts with label OData. Show all posts
Showing posts with label OData. Show all posts

Tuesday, February 10, 2015

WCF DataServices - Date Time comparison in OData query

The concept of WCF data service which uses OData is really great. But I doubt whether that is ready to be used in an enterprise production applications. The main reason is its immaturity and lack of support on some Linq queries and operators. One of the major item is lack of joins. I believe OData specification itself doesn't have join. Below is another scenario which is not supported by WCF Data Services.

Requirement - Compare date in database against current date

Lets take and scenario where a MessageProcessAttempt table is exposed via WCF Data service. There is a field called DequeuedTime which tells when a message is dequeued. We need to list down all the messages which dequeued in last 1 hour.

In normal sense we can obtain the list by subtracting the de-queued time from current time and checking if the difference < 1 hour. The query can be as follows.

List<MessageProcessingAttempt> msgs = (from msg
                           in qProxy.MessageProcessingAttempts
                           where (DateTime.UtcNow- msg.DequeuedTime.Value).TotalHours<1
                           select msg).ToList();

But it will fail with below error message
"No property 'TotalHours' exists in type 'Edm.DateTime' at position 56."
Position will change based on the code.There will be no compile time errors. It just fails at runtime. Tried to find the details about Edm.DateTime class in msdn but able to find out except one EdmDateTimeConstant class.So what can we do

Solution - Calculate target date and compare

Find the target date and do comparison rather than finding the difference in the OData query.


DateTime timeToFilter = DateTime.UtcNow.Subtract(TimeSpan.FromHours(1));
List<MessageProcessingAttempt> msgs = (from msg
                           in qProxy.MessageProcessingAttempts
                           where msg.DequeuedTime.Value >= timeToFilter
                           select msg).ToList();

Here the major difference we can notice that the date subtraction is not happening via operator and its not producing the TimeSpan obejct. We can have DateTime.UtcNow.Subtract(TimeSpan.FromHours(1)) in OData as well instead of variable and it will work. This points to the fact that TotalHours property is not there in a special type called Edm.TotalHours which is produced as part of subtraction operator.

This was found by our development team in India and I didn't agree to them in the beginning. I spend around 2-3 hours and could see WCF Data Service is still not suitable for enterprise apps. Thanks to the team for finding the workaround.

Happy coding...

Tuesday, November 19, 2013

ASP.Net MVC AJAX requests are not running in parallel when the Session is enabled

Recently I was into a mission of increasing the speed of an ASP.Net MVC web site which was continuously throwing exceptions (time outs) when the data increased to 10,000 records in one table.

Initially the site was taken care as stepchild which got less developers to work on and less allocation of design time as it is targeted to admin people who are less in number. Now the things changed suddenly and it needs to be a competitor for Facebook in terms of performance.

The main issue was due to lack of join support in OData. We fixed so many coding issues which are related to usage of WCF Data services which uses OData protocols internally. Then made most of the pages AJAX friendly. Implemented real lazy paging in grids. Earlier, the app was pulling all data to the client side and was doing paging in javascript.

The site became responsive in 5 seconds. Now a special issue got our attention. Multiple AJAX calls, we issued from javascript are not getting executed in parallel in the server side. In particular page, there are 2 AJAX requests made from jQuery. Based on the server logs, each takes 2 seconds to process. But when we looked in F12 tools, the second call ends only after 4 seconds. The search ended up in usage of session variables. By default 'only one thread can access particular Session'. In our case both the AJAX requests are executed from same page which means the execution of action methods will be serial.

Initially we though of getting rid of session usage in the whole application. But after sometime, we started thinging differently. We are not the ones who are facing this issue. Somebody might also faced it and resolved it. What they did to resolve this?

It simply ended in SessionState attribute where we can control the behaviour of session usage per Controller. Thanks to the authors of below blogs.

http://www.stefanprodan.eu/2012/02/parallel-processing-of-concurrent-ajax-requests-in-asp-net-mvc/
http://johnculviner.com/asp-net-concurrent-ajax-requests-and-session-state-blocking/

How to apply SessionState to action method level

http://sapoval.org/per-action-custom-sessionstateattribute