Isolated Context loading for Azure FunctionInvoker
Is your feature request related to a problem? Please describe.
This problem relates to a scenario when you want to use azure functions in combination with other resources in Azure and integrating them over a private network. It his case you have limited number of sub-networks you can use so separating environments by using different instances of Azure Functions is not always option. More over, even footprint of single environment can be too big for single function instance, especially if you have a lot of external dependencies that the functions are using and therefore a lot of expensive beans that have to be loaded first time any function is called which will completely blow up startup time on coldstart.
Describe the solution you'd like
Since ConfigurableApplicationContext is created on first time the FunctionInvoker constructor is called, all that has to be changes is how we initialize and store ConfigurableApplicationContext. Instead of storing it as static and we can create a singleton keyed context holder that can allow use to serve 3 scenarios:
- Function has its own context - for functions that either have no dependencies or they are called once in a while and therefore we don't want to keep their dependencies initialized all the time
- Function shares context with subset of other functions - This is to get the best out of both worlds where functions that are common in dependency footprint would share context so we have to initialize everything just once
- Function uses global context - Essentially how it behaves right now.
The ContextIndex could look something like this
public enum ContextIndex {
INSTANCE;
private final Map<String, ConfigurableApplicationContext> CONTEXT_MAP = new ConcurrentHashMap<>();
public ConfigurableApplicationContext registerContext(String label, ConfigurableApplicationContext applicationContext) {
CONTEXT_MAP.put(label, applicationContext);
return applicationContext;
}
public boolean contextExists(String label){
return CONTEXT_MAP.containsKey(label);
}
public ConfigurableApplicationContext getContext(String label) {
final ConfigurableApplicationContext context = CONTEXT_MAP.get(label);
if (context == null) {
throw new IllegalStateException("No context registered under label " + label);
}
return context;
}
}
Where label is the way functions choose what context to use. Additional if we could tie this somehow to profiles, we the label can become a profile name. This ContextIndex would be then used by FunctionInvoker to store context based on whether we used the global label or provided our own.
Alternative approach might be to take the configuration class passed to FunctionInvoker and use that class name as label for the context. That would in turn cause functions using the same configuration classes to use the same context
Seems reasonable, but I am still confused as to how one would select a particular label? IN other words how would user select which context to use?
Closing due to lack of follow up from the reporter