Improve/fix connection between app framework output provider and library streams
Currently:
-
OutputProviderhas 4 static final fields namedDEBUG_OUTPUT,NORMAL_OUTPUT,WARNING_OUTPUTandERROR_OUTPUT, that implement theDebugNormalOutput(2x),WarnOutputandErrorOutputlibrary stream interfaces. - There are
getDebugOutputStreametc static methods in that same class to get these singleton instances. - The interface methods like
WarnOutput.lineare implemented by calling static methods likewarnon the same class. These methods are turn implemented by invoking something likeAppEnv.getProvider().warnInternal(msg).
This has two implications:
- Upon each line that is written, a look-up of the application registered for the current thread has to be done, and from it the provider has to be obtained, before the relevant method of the provider can be invoked. This is relatively expensive, slowing down applications that write a lot of console output.
- In library code, where we use the library stream interfaces, we don't register any additional application threads. If there is thus a multi-threaded application, it will fail to write any output using the library stream interfaces, and crash. We noticed this while working on #1000, as the new JavaDD library is multi-threaded and crashed upon writing saturation reachability computation debug output.
This can all be fixed by not using singletons, but instead creating a new instance for each output provider of an application to bridge it to the library stream interfaces:
- Then the methods can be invoked as instance methods directly, without expensive lookups.
- They are then also tied to the provider instance, preventing the need for a lookup of the provider altogether, making it work across threads without any changes in library code.