Custom static file provider is overridden by feature - .net-6.0

I have registered a custom file provider as static file provider, but it seems to be overridden. I never get any calls to IFileInfo.CreateReadStream, but the files are still being served. The thing is I'm trying to add mem-caching for a few commonly read files, so I was implementing this in my custom file-info class on first read. But now it seems that this is overriden by IHttpSendFileFeature. This is not at all very clear. What is it that IHttpSendFileFeature does that is better than basic CreateReadStream+CopyTo? Is it implementing some kind of caching itself? Perhaps I shouldn't try add custom caching here at all. I'm not sure if file-caching is done elsewhere in the pipeline already, and perhaps much better? I'm using Kestrel on .NET 6.
I don't want to read these files from disk on every request since I'm running this on a server with mechanical discs. If I was running this with SSD's I guess I wouldn't have to worry that much about this, I mean since reads are so fast on SSD already. But also, I assume the OS do a bunch of file-paging/caching as well? So perhaps I should just skip all custom caching altogether?

Try to remove the following
app.UseStaticFiles();
which calls
app.UseMiddleware<StaticFileMiddleware>();
If you remove UseStaticFiles() and instead call
app.UseMiddleware<MyStaticFileMiddleware>();
The original StaticFileMiddleware should no longer be called.
Your Post is a little unclear to me. How do you Serve those files?
The Services / Features you describe are not registered in the default service collection.

Related

Caching and AOP in Mendix: is there a uniform or standardized approach for server-side caching within a Mendix application?

Using the Mendix Business Modeler to build web-applications is fundamentally different than developing web-applications using technologies like Java/Spring/JSF. But, I'm going to try to compare the two for the sake of this question:
In a Java/Spring based application, I can integrate my application with the 3rd party product Ehcache to cache data at the method level. For example, I can configure ehcache to store the return value for a given method (with a specific time-to-live). Whenever this method is called, ecache will automatically check if the method has been called previously with the same parameters and if there is a stored return value in the cache. If so, the method is never actually executed and instead the cached method return value is immediately returned.
I would like to have the same capabilities within Mendix, but in this case I would be caching Microflow return values. Also, I don't want to be forced to add actions all over the place explicitly telling the Microflow to check the cache. I would like to register my Microflows for caching in one centralized place, or simply flag each Microflow for being cached. In other words, this question is just as much about the concept of aspect-oriented-programming (AOP) in Mendix as it is about caching: is there a way to get hooks into Microflow invocation so I can apply pre and post execution operations? In my opinion the same reasons why AOP has it's place an purpose in Java exist in Mendix.
When working with the Mendix application it tries to do as much for you as possible, in this case that means that the platform already has an object cache to keep all objects that need caching.
Internally the Mendix platform uses Ehcache to do that.
However it is not really possible to influence that cache as you would normally do in Java/Spring.This is due to all the functionality of the Mendix Platform, that already tries to cache all objects as efficiently as possible.
Every object you create is always added to the cache. When working with that object it stays in cache until the Platform detects that the specific object can no longer be accessed either through the UI or a microflow.
There are also API calls available that instruct the platform to retain the object in cache regardless of it's usage. But that doesn't provide you with the flexibility as you asked for.
But specifically on your question, my initial response would be: Why would you want to cache a microflow output?
Objects are already cached in memory, and the browser client only refreshes the cache when instructed. Any objects that you are using will be cached.
Also when looking at most of the microflows that we use, I don't think it is likely that I would want to cache the output instead of re-running the microflows. Due to the design of the majority of the microflows I think it is likely that most microflows can return a slightly different output every time you execute it.
There are many listener classes you can subscribe to in the Mendix platform that allow you to trigger something in addition to the default action. But that would require some detailed knowledge of the current behavior.
For example you can override the login action, but if you don't perform all the correct validations you could make the login process less secure.

Using interception to implement caching - how to define keys?

TL;DR Can someone point me to a through implementation of a caching system that is added to the solution through interception?
I'm refactoring one of my solutions so that cross-cutting concerns are implemented through Unity Intercept. I've read the guides from MSFT, and now I think I can very easily implement the interception behaviors.
However, I was wondering about caching; I want to consistently use the cache regions and keys throughout the solution. Furthermore, I have key-specif configurations for expiration on my caching system.
On one example in the Unity's Developer Guide, it checks the method name -- this is a bad approach since it would mean altering the implementation everytime a new class/method must use cache (obviously).
I'm having this (mad) idea of implementing a configurable Interceptor that learns how to compose the region and key from the given parameters, and is configurable for each class(type)/method. However this would push a lot of responsibility to configuration; I don't like the feeling that I'm programming in the *.config file.
As you can see, I'm a tad bit lost on how to go about this. I don't like singletons and right now the caching system is a singleton, accessed everywhere by the solution. Can someone link me to a good documentation on how I should proceed about this? Is it possible to add cache and have proper keys/regions defined on the cache?
Quick search on the similar matter lead me to the "Attribute Based Cache using Unity Interception" project on CodePlex. Entire project looks to be abandoned in some Alpha stage, however, it should provide you with the baseline to start with.

Web service vs. class file - performance

I am trying to figure out the best way to go about doing this: I am working on a project and I'm putting all my data access layer code into .ASMX files to keep them separated from my presentation layer. I am calling all my methods from the code behind and using the web services like class files. I am following this practice based on one other developer's work. Two opinions on this so far: One says when the code-behind calls the method from the web service, it's a performance hit because it has to go do an HTTP request and the other says, no performance hit. The ASMX files are within the same project on the same server. Is there indeed a performance hit or not really? I tend to think not.
Any help or opinion on this would be appreciated.
If you call as a web service, you still have to go through the proxy and argument marshalling even if you are calling within the same server; there is a performance hit compared to calling the same class directly; the call overhead may be orders of magnitude higher. You wouldn't want to do this if the called method isn't doing some substantial work.

disable Enterprise Library Caching Application Block

We're using the Enterprise Library Caching Application Block to do caching (in memory) in our web service. Works great, no complaints.
We're starting to do some load testing, and I've been asked to disable the cache so we can get some relative idea of what kind of performance gain caching gives us. I thought this would be simple - it turns out its not.
I can't find any configuration setting to disable the cache. I suppose I could turn down the maximumElementsInCacheBeforeScavenging setting, but is there a better way?
I found one post that suggests creating your own Cache Manager that does nothing - again, is there a better way to do this?
Your best bet is to provide a custom implementation of ICacheManager (interface added in Entlib 4, can't help for earlier ones) that doesn't store anything and never gives a cache hit. Then you configure the block to use your "NullCacheManager" or whatever you want to call it.

What parts of application you prefer to be externalized as configuration and why?

What parts of your application are not coded?
I think one of the most obvious examples would be DB credentials - it's considered bad to have them hard coded. And in most of situations it is easy to decide if you want something to be externalized or coded.For me the rules are simple. Some part of the application should be externalized if:
it can and should be changed by non-developer, but not so often to be included in application settings defined in UI (DB credentials, service URLs, etc)
it does not require programming language and seems unnatural being coded (localization)
Do you have anything to add?
This is a little related to this question about spring cfg.
Spring configuration seems less obvious example for me, because in my practice it is never modified by anyone except the developer. And the road of externalizing can take you far away, to the entire project being "configured", not coded - so where to stop?
So please post here some examples from your experience, when you got benefit from having something configured, not coded - like dependency injection configuration in spring, etc.
And if you use spring - how often is configuration changed without recompiling?
Anything that needs to differ between different deployments of your application. That is, anything specific to the environment.
Examples include:
Database connection strings
URLs for web or WCF services
Logging configuration
Any information your application uses that is "data" and that could change depending on where it is installed. Things like:
smtp mail server used to send e-mails
Database connect strings
Paths to file locations / folders used by the app
FTP servers & connect info
Active Directory servers used for authentication
Any links displayed in the application to external information
sources
Warning limit values
I've even put the RegEx filters used to limit the allowable characters
for data entry fields.
Besides the obvious changing stuff (paths, servers, ports, and so on), some people argue that you should be able to easily change whatever might reasonably change, for instance, say you have a generic engine which operates on the business logic (a rule engine).
You would then define the rules on a "configuration file" which ends up being is no less than programming in a DSL instead of in the generic purpose language. Benefits being it's closer to the domain so it's easier and more maintainable, and that you can easily change things that otherwise would demand a new build.
The main argument behind this is that things you assumed would never change always end up changing nonetheless, so you better be prepared.
paths and server names/addresses come to mind..
I agree with your two conditions, which is why I:
Rarely include a config file as part of a Windows or Windows Mobile application (web apps yes).
If I did include a config file meant to be tweaked by end users, it certainly wouldn't be XML.
Employee emails/names since employees can come and go... (you should typically try to keep them out of an application though)
Configuration files should include:
deployment details
DB credentials
file paths
host names
anything that is used in many places but that may change
contact email addresses
options that aren't in the GUI
The last one is a bit open-ended, but very important. I've found it very useful to foresee variables that the client may, in the future, want to change. If changes are infrequent, I or they can edit the config file. If it becomes a frequent thing, it's trivial to add the option to the GUI, which isn't hardcoded.
I would also add encryption keys (which themselves should be encrypted)...
Basically the rule of thumb is information the application needs BEFORE it's regular, functional operation, data that it MUST have on-hand (i.e. local and not networked).
Note that this data should not be dynamically changing or large amounts of it, otherwise it should be in the database.
With Spring apps I actually distinguish between two types of configuration:
Items externalized into property files which are "deploy time" concerns or "environment-specific": server IP's / addresses, file system locations, etc etc
Spring XML configuration which can do lots of things, like indicate the overall application structure, apply behavior via AOP, etc.
I use Spring to wire all the beans in a J2SE application that has no GUI (a transactional switch). That way it's very easy for me to have different configurations in each deployment (we have this thing running in different countries), without having to code anything different.
Another thing I like to have is to manage all the SQL statements separately from the code, when I use plain JDBC (or Spring JDBC). Like in a properties file or XML or something, sometimes even as String properties in the beans that will use the statement (when there is only one bean that will use the statement, such as a DAO).
I am going to use spring JDBC or vanilla JDBC for data persistence, here we have decided to externalize all the SQL from the Java code, so can be better mangable in terms of SQL query tuning and optimization, we don't need to disturb the java code.

Resources