New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make ApplicationProvider.get asynchronous #7645
Comments
ApplicationProvider.get
asynchronous
You could consider something like this to keep object creation and indirection down a bit: // Used for atomic locking
private val reloadAtomic = new AtomicReference[Promise[Application]](null)
def getAsync(): Future[Application] = {
// Use an atomic lock to restrict access so only one
// thread reloads the application at a time.
@tailrec def atomicLoop(p: Promise[Application]): Future[Application] = reloadAtomic.get() match {
case null =>
val mkPromise = if (p eq null) Promise[Future[Application]] else p
if (reloadAtomic.compareandSet(null, mkPromise))
mkPromise.completeWith(getAsyncExclusively()).future
else atomicLoop(mkPromise)
case some => some.future
}
atomicLoop(null)
} |
OK thanks. :) And how did you even notice this ticket, do you have an email filter scanning for the word |
@richdougherty The Klang sees everything. |
For those who don't know about |
@viktorklang The Klang love |
There have been a number of issues caused by the blocking nature of
ApplicationProvider.get
: #5975, #7614, #7622. Threads get starved because every thread can end up blocking while reloading. Only one thread really needs to block—the reloading one—and the others could just wait for the result in aFuture[Application]
.I'm not implementing the change yet because we're still backporting stuff to 2.6 and this seems a bit too heavy to backport. However, here's a sketch solution so it's easy to implement later:
The text was updated successfully, but these errors were encountered: