in plugins/src/main/scala/org/apache/toree/plugins/PluginManager.scala [315:355]
private def invokePluginMethods(
pluginMethods: Seq[PluginMethod],
scopedDependencyManager: DependencyManager
): Seq[PluginMethodResult] = {
// Continue trying to invoke plugins until we finish them all or
// we reach a state where no plugin can be completed
val completedMethods = Array.ofDim[PluginMethodResult](pluginMethods.size)
// Sort by method priority and then, for ties, plugin priority
@volatile var remainingMethods = prioritizePluginMethods(pluginMethods)
@volatile var done = false
while (!done) {
// NOTE: Performing this per iteration as the global dependency manager
// can be updated by plugins with each invocation
val dm = dependencyManager.merge(scopedDependencyManager)
// Process all methods, adding any successful to completed and leaving
// any failures to be processed again
val newRemainingMethods = remainingMethods.map { case (m, i) =>
val result = m.invoke(dm)
if (result.isSuccess) completedMethods.update(i, result)
(m, i, result)
}.filter(_._3.isFailure)
// If no change detected, we have failed to process all methods
if (remainingMethods.size == newRemainingMethods.size) {
// Place last failure for each method in our completed list
newRemainingMethods.foreach { case (_, i, r) =>
completedMethods.update(i, r)
}
done = true
} else {
// Update remaining methods to past failures
remainingMethods = newRemainingMethods.map(t => (t._1, t._2))
done = remainingMethods.isEmpty
}
}
completedMethods
}