How can I put a log whenever compiler recompiles my razor view via VirtualPathProvider?

111 Views Asked by At

I'm having a bit performance problem here: the code below is part from my custom VirtualPathProvider, I've overwritten the GetCacheKey, and GetCacheDependency so they can cache my razor views properly.

public override string GetCacheKey(string virtualPath)
{
    var key = string.Empty;
    var fileResult = VerifyFilePath(virtualPath);
    if (fileResult.RefinedAccessPath.IsNotNullOrEmpty())
        key = EncryptHelper.MD5Encrypt(fileResult.RefinedAccessPath);
    else
        key = EncryptHelper.MD5Encrypt(fileResult.VirtualPath);

    return key;
}

public override string GetFileHash(string virtualPath, System.Collections.IEnumerable virtualPathDependencies)
{
    var fileResult = VerifyFilePath(virtualPath);
    var hash = string.Empty;
    if (fileResult.RefinedAccessPath.IsNotNullOrEmpty())
        hash = EncryptHelper.MD5Encrypt(fileResult.RefinedAccessPath);
    else
        hash = Previous.GetFileHash(fileResult.VirtualPath, virtualPathDependencies);

    return hash;

}
public override System.Web.Caching.CacheDependency GetCacheDependency(string virtualPath, System.Collections.IEnumerable virtualPathDependencies, DateTime utcStart)
{
    var fileResult = VerifyFilePath(virtualPath);
    switch (fileResult.Result)
    {
        case ExistenceResult.FoundInCloudAfterRebuildPath:
        case ExistenceResult.FoundInCloudDirectly:
            return new OSiteCacheDependency(fileResult.LastModified, ositeVirtualPathHelper.SiteID.ToString(), utcStart);
        default:
            if (fileResult.RefinedAccessPath.IsNotNullOrEmpty())
                return new System.Web.Caching.CacheDependency(fileResult.RefinedAccessPath);
            else
                return null;
    }
}

However currently I'm a bit concerned whether my code is correct or not - because when I test it on my local PC, it works perfectly, however if I upload it to Azure websites, it takes AGES to get the pages rendered.

The views are stored on Azure Blob storage, and I put log entries on the GetFile and find they are cached, however it does look like the website is getting constantly recompiled on each page (yes each page, because when it is compiled if I refresh the Azure website page it gets displayed instantly, but not other pages that I haven't visited)

So my first guess is - Azure website performance is very poor, however then I upgraded it to P3 Large Instance Web App Service Plan and got still the same problem. So it made me thinking do I have any error the in VirtualPathProvider again? As GetFile() method is not always hit and the visited page gets displayed immediate after refresh, I'm sure the caching is also working, so it leaves me thinking whether there's any other compilation happening during the process that causes each page taking so much time for the first load?

Can anyone help please...

Thanks in advance.

1

There are 1 best solutions below

0
On

Hi for those who are interested to know the outcome of this issue:

well I didn't find out a perfect solution however I did find out that after deploying the website onto a Cloud Service it solved the issue almost immediately....

There's no difference in code, in deployment or anything in the views, but I guess there's a problem on dedicated resources comparing Azure Websites v.s. Cloud service (even with the fact I had tried Large instance Azure website, it didn't compete with the Standard medium size Cloud service instance for some reason.)

I'm sure millions are using Azure so there's no doubt my code is certainly having some critical performance issue. I have to firstly make it functioning by using Cloud Service, and then try to find a way to optimize it after the deployment (otherwise our clients will drive us mad!)

So what happened:

Complexity 1) Our application is actually a multi-tenant ASP.NET MVC website which renders websites for our customers (i.e. website builder). We allow customers to have their own code in Razor Views so that comes with a sacrifice of performance impact in compilation (hence our problem in the topic)

Complexity 2) All our clients' websites are totally different and views are stored in Azure Blob Storage! (We have another separate back-end system for them to manage these websites) Therefore, we cannot use local file system for the views - i.e. default ASP.NET MVC View Engine won't work, and by doing a basic custom view engine will not work either which lead us implementing our own VirutalPathProvider and CacheDependency

Complexity 3) Our website are managed using our own internal OAuth server, so basically all data retreived in the website are through internal API calls, which delays the view rendering time too.

We've been working weekends and nights in the past few weeks solving complexity 2) and now getting extremely frustrated by the poor performance at the moment.

Literally we sit together at 2am mid-night thinking what went wrong and made the fundamental key factors as above. We will tackle around Complexity 3) for sure, but for Complexity 1) we have to temporarily choose Cloud Service to solve the issue (Still slow, but at least the websites can be opened in an acceptable time)

Frustration also came when we use our own dedicated server, VPS and even Azure VM everything worked with no issue (websites rendered in the platform can be opened in our local debug mode within 2 seconds no mention the remote connection to Azure SQL and Blob Storage.)

So myths are still there, ultimate solution not found yet. But decision has been made that we will work with the current speed and current Cloud Service for now, and make further investigation later when we settle down our customers first...

Anyone has any clue or realize what we've done wrong based on my writings above, please let me know - highly appreciated!