markusthoemmes commented on a change in pull request #2414: SPI approach for 
pluggable implementations
URL: 
https://github.com/apache/incubator-openwhisk/pull/2414#discussion_r131227962
 
 

 ##########
 File path: docs/spi.md
 ##########
 @@ -0,0 +1,75 @@
+# SPI extensions in OpenWhisk
+
+Alternate implementations of various components follow an SPI (Service 
Provider Interface) pattern:
+* The pluggable component is defined as an Spi trait:
+```scala
+import whisk.spi.Spi
+trait ThisIsPluggable extends Spi { ... }
+```
+* Implementations implement the Spi trait
+```scala
+class TheImpl extends ThisIsPluggable { ... }
+class TheOtherImpl extends ThisIsPluggable { ... }
+```
+
+Runtime resolution of an Spi trait to a specific impl is provided by:
+* SpiLoader - a utility for loading the impl of a specific Spi, using a 
resolver to determine the impls factory classname, and reflection to load the 
factory object
+* SpiFactory - a way to define a factory for each impl, all of which are 
loaded via reflection
+* application.conf - each SpiFactory is resolved to a classname based on the 
config key provided to SpiLoader
+
+A single SpiFactory per unique Spi is usable at runtime, since the key will 
have a single string value. 
+
+# Example
+
+The process to create and use an SPI is as follows:
+
+## Define the Spi and impl(s)
+
+* create your Spi trait `YourSpi` as an extension of whisk.spi.Spi
+* create your impls as classes that extend `YourSpi`
+
+## Define the SpiFactory to load the impl
+
+```scala
+class YourImplFactory extends SpiFactory[YourSpi]{
+  def apply(dependencies: Dependencies): { ...construct the impl...}
+}
+```
+for singleton behavior you can use
+```scala
+class YourImplFactory extends SingletonSpiFactory[YourSpi]{
+  def buildInstance(dependencies: Dependencies): { ...construct the impl...}
+}
+```
+
+## Invoke SpiLoader.instanceOf to acquire an instance of the SPI
+
+SpiLoader accepts a key to use for resolving which impl should be loaded. The 
mapping of key to classname is implemented in an instance of 
`whisk.spi.SpiClassResolver`
+Example whisk.spi.SpiClassResolver impls are:
+* whisk.spi.ClassnameResolver - classname is not interpreted by used literally 
from the value of the key
+* whisk.spi.TypesafeConfigClassResolver - classname is looked up as a String 
from the provided instance of com.typesafe.config.Config (available via 
`ActorSystem.settings.config` within an Akka app)
+
+Invoke the loader using `SpiLoader.instanceOf[<the SPI interface>](<key to 
resolve the classname>)(<implicit resolver>)`
+
+The configKey indicates which config (in application.conf) is used to 
determine which impl is used at runtime.
+```scala
+val messagingProvider = 
SpiLoader.instanceOf[MessagingProvider]("whisk.spi.messaging.impl")
 
 Review comment:
   Outdated.
 
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to