1
Blob Cache Understanding Problem
Problem reported by Patrick Riehmers - 11/3/2023 at 12:47 AM
Resolved
Hi all,

i have the followed scenario with 2 Applications, which shares the same Files and Cache Location
(Doc Ultimate Version 6.9.5)

1. ASP.NET Framework v4.8 Web Application
2. .NET 6.0 Core Web Application

They have both the same configuration for DocUltimate, use the same StreamFileProvider, with the exact same information for the same file. If run them localy with VS 2022, both applications use the same Cache file. I did some checks with CreateCacheInfo, localy thats the same!
Now, if i publish them to the Azure App Service, the 1. App (Framework v4.8) use the same Cache file BUT the .NET Core Application use a complete different Cache file.

ASP.NET Core localy & .NET Framework localy and in Azure

ASP.NET Core on Azure - Trace from Application Insight, where i log the CacheSourceKey:

Does anybody has an simular issue and knows how to solve this? @Cem, do you have some Information, how that Cache Key is created? 3 of 4 generates the same Key, only the online Azure .NET Core Application does it another way.

Thanks alot,
best wishes
Patrick

3 Replies

Reply to Thread
0
Cem Alacayir Replied
Employee Post Marked As Resolution
From the docs:

For generating the cache key, to uniquely identify a document file, we use a string combination of file extension, file size and file date, this way cache collisions do not occur and we can reuse the cached file even if the file name before extension is changed (file1.docx and file2.docx have same cache key because it's still the same document according to file extension, file size and file date).

File providers like FileSystemFileProvider (a file on disk, on Amazon S3, on Azure) can provide file size and file date automatically however some file providers will not have this knowledge, e.g.StreamFileProvider, MemoryFileProvider (how could they know date modified of your data in a byte array or a stream?).

So for this purpose, these kind of providers have an additional property or constructor argument named DateModified and/or Size. You need to specify these to ensure you uniquely identify a document.

Do you store the files on Azure Blob ? If so DateModified metadata is retrieved from there and if it's same blob and you get a different DateModified on .NET Framework and .NET 6.0, then used Microsoft.Azure.Storage.Blob library may have a difference for 2 platforms

But you say you use StreamFileProvider, then you need to provide DateModified and if stream is not seekable Size yourself:

FileProvider fileProvider;

//Setting a StreamFileProvider instance,
//to connect to a file in a Stream:
//Optional parameters dateModified and size: used for detailed file info, e.g. for generating better cache keys.
fileProvider = new StreamFileProvider(
    "SomeFile.ext", //file can also be set as a relative path "SomeFolder/SomeFile.ext".
    yourStream,
    yourFileDateModified, //Provide dateModified to prevent cache key conflicts.
    yourFileSize //Provide size only if your stream is not seekable to prevent cache key conflicts.
);
0
Patrick Riehmers Replied
Hi Cem,

thanks for your reply. Yes, both applications use the same Azure Blob Storage and indeed, we think there was a missinformation from the Microsoft.Azure.Storage.Blob Library by getting the file size information and in that case, two different cachefolder were created.


1
Cem Alacayir Replied
Employee Post
So do you mean you were using StreamFileProvider to access Azure Blob in a custom way (and not FileSystemFileProvider)? In that case, you should handle the DateModified yourself, for example in our code we retrieve it as follows:

DateModified = TryGetDateTime(cloudBlob.Metadata, "DateModified", out var dateModified) 
        ? dateModified 
        : cloudBlob.Properties.LastModified.GetValueOrDefault().UtcDateTime;

private static bool TryGetDateTime(IDictionary<string, string> dictionary, string key, out DateTime dateTime)
{
    if (dictionary.TryGetValue(key, out var dateTimeString))
    {
        dateTime = DateTimeExtensions.FromIsoDateString(dateTimeString);
        return true;
    }

    dateTime = default;
    return false;
}

So if use our Azure Blob file provider it already handles DateModified via above code internally:

//Setting a FileSystemFileProvider instance with an AzureBlobLocation instance,
//to connect to Azure Blob cloud file system.
documentViewer.Document = new FileSystemFileProvider
{
    File = "Document.docx",
    Location = new AzureBlobLocation
    {
        //Leave Path empty to connect to the root of the container. 
        //For connecting to subfolders, Path should be specified as a relative path (eg. "some/folder")
        //Path = "some/folder",

        //Get these values from your Azure Portal (Storage Account -> Access Keys -> Connection String)
        Container = "CONTAINER",
        AccountName = "XXX",
        AccountKey = "XXX"
    }
};

Reply to Thread