I have a actionresult that I think is pretty heavy, so I wonder how can I optimize it so it gets better performance. This web application will be used for by +100, 000 users at same time.
Right now my Actionresult does the following things:
- Retrieve XML file from a internet url
- Fills the xml data to my DB
- DB data fills my Viewmodel
- Returns the model to the view
This 4 functions triggers everytime a user visits the view. This is why I think this Actionresult is very badly made by me.
How can I add this following things to my Actionresults?
add a timer to retrieve XML file and fill xml data to DB, like every 10 minute, so it doesnt trigger everytime a user visits the view. The only function that needs to trigger everytime a user visits the site is the viewmodel binding and returning the model. How can I accomplish this?
Note:
- the xml file gets updated with new data every 10 min or so.
- I have around 50 actionresults that does the same get xml data and adds to database but 50 different xml files.
- If the xml URL is offline it should skip the whole xml retrieve and DB add and just do the modelbinding
This is my actionresult:
public ActionResult Index()
{
//Get data from xml url (This is the code that shuld not run everytime a user visits the view)
var url = "http://www.interneturl.com/file.xml";
XNamespace dcM = "http://search.yahoo.com/mrss/";
var xdoc = XDocument.Load(url);
var items = xdoc.Descendants("item")
.Select(item => new
{
Title = item.Element("title").Value,
Description = item.Element("description").Value,
Link = item.Element("link").Value,
PubDate = item.Element("pubDate").Value,
MyImage = (string)item.Elements(dcM + "thumbnail")
.Where(i => i.Attribute("width").Value == "144" && i.Attribute("height").Value == "81")
.Select(i => i.Attribute("url").Value)
.SingleOrDefault()
})
.ToList();
//Fill my db entities with the xml data(This is the code that shuld not run everytime a user visits the view)
foreach (var item in items)
{
var date = DateTime.Parse(item.PubDate);
if (!item.Title.Contains(":") && !(date <= DateTime.Now.AddDays(-1)))
{
News NewsItem = new News();
Category Category = new Category();
var CategoryID = 2;
var WorldCategoryID = re.GetByCategoryID(CategoryID);
NewsItem.Category = WorldCategoryID;
NewsItem.Description = item.Description;
NewsItem.Title = item.Title.Replace("'", "");
NewsItem.Image = item.MyImage;
NewsItem.Link = item.Link;
NewsItem.Date = DateTime.Parse(item.PubDate);
re.AddNews(NewsItem);
re.save();
}
}
//All code below this commenting needs to run everytime a user visits the view
var GetAllItems = re.GetAllWorldNewsByID();
foreach (var newsitemz in GetAllItems)
{
if (newsitemz.Date <= DateTime.Now.AddDays(-1))
{
re.DeleteNews(newsitemz);
re.save();
}
}
var model = new ItemViewModel()
{
NewsList = new List<NewsViewModel>()
};
foreach (var NewsItems in GetAllItems)
{
FillProductToModel(model, NewsItems);
}
return View(model);
}
Right now everytime a user visits the index view, it will get XML data and add it to the DB, so the bad fix Ive done in my repository is following on addNews:
public void AddNews(News news)
{
var exists = db.News.Any(x => x.Title == news.Title);
if (exists == false)
{
db.News.AddObject(news);
}
else
{
db.News.DeleteObject(news);
}
}
Any kind of solution and info is highly appreciated!