Currently CorDapp developers have access to Corda persistence via the flow framework and Corda services. However, it might be the case that some work needs to be performed on another thread. Trying to access `CordaPersistence` from another thread results in the following exception:
Caused by: java.lang.IllegalStateException: Was expecting to find CordaPersistence set on current thread: Thread[RxIoScheduler-2,5,main]
This is because there's no `ThreadLocal` instance of `CordaPersistence` available. It would be useful if there was an API for CorDapp developers to wrap vault calls etc. in a database transaction block. This would allow developers to perform tasks that require node database access in separate threads.
Maybe we can provide an API to register asynchronous actions so that the platform can manage them.
Edit: Actually we already have FlowAsyncOperation. So maybe we can create another version FlowAsyncDBOperation where execute would expose a CordaPersistence
Could we make the TLS slot an InheritableThreadLocal - would that also fix it? Does the CordaPersistence require thread affinity?
I'm wondering, why does CordaPersistence need to be a (Inheritable)ThreadLocal in the first place if it does not require any thread affinity?
Can't it be a singleton?
It is basically a proxy for the DataSource to get Connections, which need to be ThreadLocal.
while your point is correct, it's the DataSource which is not thread-safe and needs to be in a ThreadLocal, there's not harm in terms of performance in having CordaPersistence in a ThreadLocal instead.
Changing the logic to have DataSource in an InheritableThreadLocal and CordaPersistence as a singleton would be a very big change, for we access this type widely in the codebase, including the usage of implicit global variables e.g., "contextDatabase: CordaPerisistence".
The DataSource is basically just a wrapper over a connection pool implementation.
In our case it's Hikari, which is thread safe.
If this wasn't the case, we couldn't store CordaPersistence in an InheritableThreadLocal either.