MVC3 - using AsyncController to prepopulate ObjectCache from database
I have a form that searches via AJAX against two different data sources. The data is relatively small but the speed at which it returns is slow.
I built a cache layer to store the full result after the first query... however, I would like to prime the cache with data before the user executes the search.
Should I be looking at an AsyncController to do t开发者_JS百科his? Any recommendations?
My desired behavior is (updated):
- User requests any ActionABC of some controller (not necessarily the search action)
- Server-side, that action checks the cache and asynchronously requests data if empty
- ActionABC returns requested view while cache continues to populate on server
- If the user subsequently performs a search while cache being populated, their request waits until cache populate is complete otherwise cache data is immediately available
You would get a benefit from an async controller only if you could perform the 2 searches in parallel.
In this case your logic could be:
- If the data is found in the cache return the result immediately.
- If the data is not found in the cache launch 2 parallel async tasks to perform the search.
- Synchronize those tasks so that once they both finish you populate the cache and return the final result.
Also if you are going the AsyncController route make sure you use async ADO.NET API to query your database (command.BeginExecuteResult
/command.EndExecuteResult
) so that you can take full advantage of I/O Completion ports and do not block worker threads during the execution of the expensive search operations.
I ended up not having to use AsyncControllers.
I used the Task Factory to "fire and forget" a call to load the data initially upon any call to the controller.
Task.Factory.StartNew(() => { var x = GetData(); });
Inside "GetData" call I used LOCK to force subsequent calls to wait until cache was populated (addresses #4)
private static object ThisLock = new object();
protected MyData GetData()
{
if(<MyData in cache>)
return MyData from cache;
lock(ThisLock)
{
// just entered lock, see if cache was set by previous blocking thread
if(MyData in cache>)
return data from cache;
... load MyData from database ...
... save MyData to cache ...
return MyData from cache;
}
}
精彩评论