{"action":"created","issue":{"url":"https://api.github.com/repos/aspnet/ResponseCaching/issues/11","repository_url":"https://api.github.com/repos/aspnet/ResponseCaching","labels_url":"https://api.github.com/repos/aspnet/ResponseCaching/issues/11/labels{/name}","comments_url":"https://api.github.com/repos/aspnet/ResponseCaching/issues/11/comments","events_url":"https://api.github.com/repos/aspnet/ResponseCaching/issues/11/events","html_url":"https://github.com/aspnet/ResponseCaching/issues/11","id":166407602,"number":11,"title":"Create a Middleware to propose an implementation of 'IHttpSendFileFeature'","user":{"login":"Yves57","id":11701094,"avatar_url":"https://avatars.githubusercontent.com/u/11701094?v=3","gravatar_id":"","url":"https://api.github.com/users/Yves57","html_url":"https://github.com/Yves57","followers_url":"https://api.github.com/users/Yves57/followers","following_url":"https://api.github.com/users/Yves57/following{/other_user}","gists_url":"https://api.github.com/users/Yves57/gists{/gist_id}","starred_url":"https://api.github.com/users/Yves57/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Yves57/subscriptions","organizations_url":"https://api.github.com/users/Yves57/orgs","repos_url":"https://api.github.com/users/Yves57/repos","events_url":"https://api.github.com/users/Yves57/events{/privacy}","received_events_url":"https://api.github.com/users/Yves57/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":4,"created_at":"2016-07-19T18:56:19Z","updated_at":"2016-07-30T15:28:35Z","closed_at":null,"body":"Better repository for issue aspnet/KestrelHttpServer#981...\r\nI have made some performance tests to see the difference between using a cache and using directly a physical file stream.\r\n- When using a cache, I use a dictionary to store the last modification date (in case of the file is modified) and the file content.\r\n- When using directly the file, I have more or less copy/paste the `StaticFiles.StaticFileContext` code (including `StreamCopyOperation.CopyToAsync()`).\r\nI created a Console application, and I made tries with different file sizes. For each file size, I loop 1000 times on the same file to copy it to the `Null` stream (to avoid uninteresting overhead). So it is the most favorable case for the physical file stream, because Windows and the hard disc can do the best use of their caches.\r\n\r\nHere are the results on my computer:\r\n```\r\nTest with cache\r\n10K --> 52 ms\r\n30K --> 38 ms\r\n100K --> 36 ms\r\n500K --> 35 ms\r\n1M --> 36 ms\r\n5M --> 42 ms\r\n10M --> 51 ms\r\n\r\nTest direct stream\r\n10K --> 148 ms\r\n30K --> 132 ms\r\n100K --> 179 ms\r\n500K --> 425 ms\r\n1M --> 728 ms\r\n5M --> 4138 ms\r\n10M --> 8525 ms\r\n```\r\n\r\nThe performance difference is significant!\r\n\r\nSo I suggest to add a middleware with the following options:\r\n```\r\npublic class SendPhysicalFileCacheOptions\r\n{\r\n   public int CacheMaximumSize { get; set; }   // The maximum dedicated size in MB (i.e. the sum of all file contents)\r\n   public long FileMaximumSize { get; set; }   // The maximum size of a file to be saved in cache in Bytes (so lower than CacheMaximumSize)\r\n   public IEnumerable<Func<string, long, bool>> Filters { get; set; } // Optional filters F(filePath, fileLength)->bool that allows user the reject files from cache\r\n}\r\n```"},"comment":{"url":"https://api.github.com/repos/aspnet/ResponseCaching/issues/comments/236371292","html_url":"https://github.com/aspnet/ResponseCaching/issues/11#issuecomment-236371292","issue_url":"https://api.github.com/repos/aspnet/ResponseCaching/issues/11","id":236371292,"user":{"login":"Yves57","id":11701094,"avatar_url":"https://avatars.githubusercontent.com/u/11701094?v=3","gravatar_id":"","url":"https://api.github.com/users/Yves57","html_url":"https://github.com/Yves57","followers_url":"https://api.github.com/users/Yves57/followers","following_url":"https://api.github.com/users/Yves57/following{/other_user}","gists_url":"https://api.github.com/users/Yves57/gists{/gist_id}","starred_url":"https://api.github.com/users/Yves57/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Yves57/subscriptions","organizations_url":"https://api.github.com/users/Yves57/orgs","repos_url":"https://api.github.com/users/Yves57/repos","events_url":"https://api.github.com/users/Yves57/events{/privacy}","received_events_url":"https://api.github.com/users/Yves57/received_events","type":"User","site_admin":false},"created_at":"2016-07-30T15:28:35Z","updated_at":"2016-07-30T15:28:35Z","body":"I have a an alternative idea, perhaps more elegant. Instead of creating a middleware, it is possible to create a `MemoryCacheFileProvider` (that implements `IFileProvider`) in FileSystem:\r\n- No additionnal middleware in the middleware stack.\r\n- it let the `IHttpSendFileFeature` interface free to be implemented.\r\n- it authorize the user to setup the cache parameters file provider by file provider.\r\n- it works with any kind of file provider, not just the physical file provider.\r\n- it can be used in other file access scenarios\r\n\r\nThe source code should be something like:\r\n```\r\nvar fileProvider = new PhysicalFileProvider(....);\r\nvar cacheProvider = new MemoryCacheFileProvider(fileProvider, options);\r\n```"}}
{"actor":{"display_login":"Yves57"}}