There's an async method in some external library, which is not thread-safe (corrupts internal state when being called concurrently) and is very unlikely to be ever fixed in the near future. Yet I want the rest of my codebase to freely use it in any possible parallel vs. sequential combinations (in other words, I want my methods that use that method to still be thread-safe).
So I need to wrap that problematic method with some Active Object implementation, so that its invocations are always aligned (executed one after another).
My take on this is to use a chain of Promises:
var workQueue: Promise<any> = Promise.resolve();
function executeSequentially<T>(action: () => Promise<T>): Promise<T> {
return new Promise((resolve, reject) => {
workQueue = workQueue.then(() => {
return action().then(resolve, reject);
});
});
}
And then instead of directly calling that method:
const myPromise = asyncThreadUnsafeMethod(123);
I'll be calling it like this:
const myPromise = executeSequentially(() => asyncThreadUnsafeMethod(123));
But am I missing something? Any potential problems with this approach? Any better ideas?