{"action":"created","comment":{"url":"https://api.github.com/repos/apache/incubator-openwhisk/pulls/comments/131178209","pull_request_review_id":54134200,"id":131178209,"diff_hunk":"@@ -0,0 +1,94 @@\n+package whisk.spi\n+\n+import com.typesafe.config.Config\n+import java.util.concurrent.atomic.AtomicReference\n+import scala.reflect.ClassTag\n+\n+/*\n+ * Licensed to the Apache Software Foundation (ASF) under one or more\n+ * contributor license agreements.  See the NOTICE file distributed with\n+ * this work for additional information regarding copyright ownership.\n+ * The ASF licenses this file to You under the Apache License, Version 2.0\n+ * (the \"License\"); you may not use this file except in compliance with\n+ * the License.  You may obtain a copy of the License at\n+ *\n+ *     http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+\n+trait Spi {\n+}\n+\n+trait SpiFactory[T <: Spi] {\n+    def apply(dependencies: Dependencies): T\n+}\n+\n+trait SingletonSpiFactory[T <: Spi] extends SpiFactory[T]{\n+    private val ref = new AtomicReference[T]()\n+    def buildInstance(dependencies: Dependencies): T\n+    override def apply(dependencies: Dependencies): T = {\n+        val oldValue = ref.get()\n+        if (oldValue != null.asInstanceOf[T]) {\n+            oldValue\n+        } else {\n+            val newValue = buildInstance(dependencies)\n+            if (ref.compareAndSet(null.asInstanceOf[T], newValue)){\n+                newValue\n+            } else {\n+                ref.get()\n+            }\n+        }\n+    }\n+}\n+\n+trait SpiClassResolver {\n+    def getClassnameForKey(key: String): String\n+}\n+\n+object SpiLoader {\n+    def instanceOf[A <: Spi](key: String, deps: Dependencies = new Dependencies())(implicit resolver: SpiClassResolver = ClassnameResolver, tag: ClassTag[A]): A = {\n+        val clazz = Class.forName(resolver.getClassnameForKey(key) + \"$\")\n+        clazz.getField(\"MODULE$\").get(clazz).asInstanceOf[SpiFactory[A]].apply(deps)\n+    }\n+}\n+\n+/**\n+ * Classname is specified directly at the time of lookup\n+ */\n+object ClassnameResolver extends SpiClassResolver {\n+    override def getClassnameForKey(key: String): String = key\n+}\n+\n+/**\n+ * Lookup the classname for the SPI impl based on a key in the provided Config\n+ * @param config\n+ */\n+class TypesafeConfigClassResolver(config: Config) extends SpiClassResolver {\n+    override def getClassnameForKey(key: String): String = config.getString(key)\n+}","path":"common/scala/src/main/scala/whisk/spi/SpiLoader.scala","position":72,"original_position":73,"commit_id":"6b404f5c34d59652ac4a77587bd668a96c8a770c","original_commit_id":"85372477615dbbc4b595f36f7b727d08807f1d46","user":{"login":"tysonnorris","id":1638396,"avatar_url":"https://avatars1.githubusercontent.com/u/1638396?v=4","gravatar_id":"","url":"https://api.github.com/users/tysonnorris","html_url":"https://github.com/tysonnorris","followers_url":"https://api.github.com/users/tysonnorris/followers","following_url":"https://api.github.com/users/tysonnorris/following{/other_user}","gists_url":"https://api.github.com/users/tysonnorris/gists{/gist_id}","starred_url":"https://api.github.com/users/tysonnorris/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tysonnorris/subscriptions","organizations_url":"https://api.github.com/users/tysonnorris/orgs","repos_url":"https://api.github.com/users/tysonnorris/repos","events_url":"https://api.github.com/users/tysonnorris/events{/privacy}","received_events_url":"https://api.github.com/users/tysonnorris/received_events","type":"User","site_admin":false},"body":"Ah sure, I was propagating the Akka config previously. I'm not sure there is any difference in (re)constructing the config directly via TypesafeConfig, but this will certainly remove the leaky class resolver. I will set it as the default","created_at":"2017-08-03T15:38:00Z","updated_at":"2017-08-03T15:38:00Z","html_url":"https://github.com/apache/incubator-openwhisk/pull/2414#discussion_r131178209","pull_request_url":"https://api.github.com/repos/apache/incubator-openwhisk/pulls/2414","_links":{"self":{"href":"https://api.github.com/repos/apache/incubator-openwhisk/pulls/comments/131178209"},"html":{"href":"https://github.com/apache/incubator-openwhisk/pull/2414#discussion_r131178209"},"pull_request":{"href":"https://api.github.com/repos/apache/incubator-openwhisk/pulls/2414"}}},"pull_request":{"url":"https://api.github.com/repos/apache/incubator-openwhisk/pulls/2414","id":127050967,"html_url":"https://github.com/apache/incubator-openwhisk/pull/2414","diff_url":"https://github.com/apache/incubator-openwhisk/pull/2414.diff","patch_url":"https://github.com/apache/incubator-openwhisk/pull/2414.patch","issue_url":"https://api.github.com/repos/apache/incubator-openwhisk/issues/2414","number":2414,"state":"open","locked":false,"title":"SPI approach for pluggable implementations","user":{"login":"tysonnorris","id":1638396,"avatar_url":"https://avatars1.githubusercontent.com/u/1638396?v=4","gravatar_id":"","url":"https://api.github.com/users/tysonnorris","html_url":"https://github.com/tysonnorris","followers_url":"https://api.github.com/users/tysonnorris/followers","following_url":"https://api.github.com/users/tysonnorris/following{/other_user}","gists_url":"https://api.github.com/users/tysonnorris/gists{/gist_id}","starred_url":"https://api.github.com/users/tysonnorris/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tysonnorris/subscriptions","organizations_url":"https://api.github.com/users/tysonnorris/orgs","repos_url":"https://api.github.com/users/tysonnorris/repos","events_url":"https://api.github.com/users/tysonnorris/events{/privacy}","received_events_url":"https://api.github.com/users/tysonnorris/received_events","type":"User","site_admin":false},"body":"This set of changes introduces SPI concepts and example default spi + impls for:\r\n- db (ArtifactStoreProvider + CouchDBStoreProvider)\r\n- messaging (MessagingProvider + KafkaMessagingProvider)\r\n\r\nwill likely need a bit of cleanup, but should be enough to get the discussion started ","created_at":"2017-06-22T17:53:31Z","updated_at":"2017-08-03T15:38:00Z","closed_at":null,"merged_at":null,"merge_commit_sha":"2f8298ec37e3e9b891cf42a8e72b632dc005f0ff","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/apache/incubator-openwhisk/pulls/2414/commits","review_comments_url":"https://api.github.com/repos/apache/incubator-openwhisk/pulls/2414/comments","review_comment_url":"https://api.github.com/repos/apache/incubator-openwhisk/pulls/comments{/number}","comments_url":"https://api.github.com/repos/apache/incubator-openwhisk/issues/2414/comments","statuses_url":"https://api.github.com/repos/apache/incubator-openwhisk/statuses/6b404f5c34d59652ac4a77587bd668a96c8a770c","head":{"label":"tysonnorris:spi","ref":"spi","sha":"6b404f5c34d59652ac4a77587bd668a96c8a770c","user":{"login":"tysonnorris","id":1638396,"avatar_url":"https://avatars1.githubusercontent.com/u/1638396?v=4","gravatar_id":"","url":"https://api.github.com/users/tysonnorris","html_url":"https://github.com/tysonnorris","followers_url":"https://api.github.com/users/tysonnorris/followers","following_url":"https://api.github.com/users/tysonnorris/following{/other_user}","gists_url":"https://api.github.com/users/tysonnorris/gists{/gist_id}","starred_url":"https://api.github.com/users/tysonnorris/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tysonnorris/subscriptions","organizations_url":"https://api.github.com/users/tysonnorris/orgs","repos_url":"https://api.github.com/users/tysonnorris/repos","events_url":"https://api.github.com/users/tysonnorris/events{/privacy}","received_events_url":"https://api.github.com/users/tysonnorris/received_events","type":"User","site_admin":false},"repo":{"id":85763317,"name":"openwhisk","full_name":"tysonnorris/openwhisk","owner":{"login":"tysonnorris","id":1638396,"avatar_url":"https://avatars1.githubusercontent.com/u/1638396?v=4","gravatar_id":"","url":"https://api.github.com/users/tysonnorris","html_url":"https://github.com/tysonnorris","followers_url":"https://api.github.com/users/tysonnorris/followers","following_url":"https://api.github.com/users/tysonnorris/following{/other_user}","gists_url":"https://api.github.com/users/tysonnorris/gists{/gist_id}","starred_url":"https://api.github.com/users/tysonnorris/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tysonnorris/subscriptions","organizations_url":"https://api.github.com/users/tysonnorris/orgs","repos_url":"https://api.github.com/users/tysonnorris/repos","events_url":"https://api.github.com/users/tysonnorris/events{/privacy}","received_events_url":"https://api.github.com/users/tysonnorris/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/tysonnorris/openwhisk","description":"Apache OpenWhisk is a serverless event-based programming service and an Apache Incubator project","fork":true,"url":"https://api.github.com/repos/tysonnorris/openwhisk","forks_url":"https://api.github.com/repos/tysonnorris/openwhisk/forks","keys_url":"https://api.github.com/repos/tysonnorris/openwhisk/keys{/key_id}","collaborators_url":"https://api.github.com/repos/tysonnorris/openwhisk/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/tysonnorris/openwhisk/teams","hooks_url":"https://api.github.com/repos/tysonnorris/openwhisk/hooks","issue_events_url":"https://api.github.com/repos/tysonnorris/openwhisk/issues/events{/number}","events_url":"https://api.github.com/repos/tysonnorris/openwhisk/events","assignees_url":"https://api.github.com/repos/tysonnorris/openwhisk/assignees{/user}","branches_url":"https://api.github.com/repos/tysonnorris/openwhisk/branches{/branch}","tags_url":"https://api.github.com/repos/tysonnorris/openwhisk/tags","blobs_url":"https://api.github.com/repos/tysonnorris/openwhisk/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/tysonnorris/openwhisk/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/tysonnorris/openwhisk/git/refs{/sha}","trees_url":"https://api.github.com/repos/tysonnorris/openwhisk/git/trees{/sha}","statuses_url":"https://api.github.com/repos/tysonnorris/openwhisk/statuses/{sha}","languages_url":"https://api.github.com/repos/tysonnorris/openwhisk/languages","stargazers_url":"https://api.github.com/repos/tysonnorris/openwhisk/stargazers","contributors_url":"https://api.github.com/repos/tysonnorris/openwhisk/contributors","subscribers_url":"https://api.github.com/repos/tysonnorris/openwhisk/subscribers","subscription_url":"https://api.github.com/repos/tysonnorris/openwhisk/subscription","commits_url":"https://api.github.com/repos/tysonnorris/openwhisk/commits{/sha}","git_commits_url":"https://api.github.com/repos/tysonnorris/openwhisk/git/commits{/sha}","comments_url":"https://api.github.com/repos/tysonnorris/openwhisk/comments{/number}","issue_comment_url":"https://api.github.com/repos/tysonnorris/openwhisk/issues/comments{/number}","contents_url":"https://api.github.com/repos/tysonnorris/openwhisk/contents/{+path}","compare_url":"https://api.github.com/repos/tysonnorris/openwhisk/compare/{base}...{head}","merges_url":"https://api.github.com/repos/tysonnorris/openwhisk/merges","archive_url":"https://api.github.com/repos/tysonnorris/openwhisk/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/tysonnorris/openwhisk/downloads","issues_url":"https://api.github.com/repos/tysonnorris/openwhisk/issues{/number}","pulls_url":"https://api.github.com/repos/tysonnorris/openwhisk/pulls{/number}","milestones_url":"https://api.github.com/repos/tysonnorris/openwhisk/milestones{/number}","notifications_url":"https://api.github.com/repos/tysonnorris/openwhisk/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/tysonnorris/openwhisk/labels{/name}","releases_url":"https://api.github.com/repos/tysonnorris/openwhisk/releases{/id}","deployments_url":"https://api.github.com/repos/tysonnorris/openwhisk/deployments","created_at":"2017-03-21T23:19:45Z","updated_at":"2017-03-21T23:19:47Z","pushed_at":"2017-08-03T14:14:28Z","git_url":"git://github.com/tysonnorris/openwhisk.git","ssh_url":"git@github.com:tysonnorris/openwhisk.git","clone_url":"https://github.com/tysonnorris/openwhisk.git","svn_url":"https://github.com/tysonnorris/openwhisk","homepage":"http://openwhisk.org","size":56172,"stargazers_count":0,"watchers_count":0,"language":"Scala","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"apache:master","ref":"master","sha":"d29c45298606f8640ef6293e491ffa1a7cb9b649","user":{"login":"apache","id":47359,"avatar_url":"https://avatars0.githubusercontent.com/u/47359?v=4","gravatar_id":"","url":"https://api.github.com/users/apache","html_url":"https://github.com/apache","followers_url":"https://api.github.com/users/apache/followers","following_url":"https://api.github.com/users/apache/following{/other_user}","gists_url":"https://api.github.com/users/apache/gists{/gist_id}","starred_url":"https://api.github.com/users/apache/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apache/subscriptions","organizations_url":"https://api.github.com/users/apache/orgs","repos_url":"https://api.github.com/users/apache/repos","events_url":"https://api.github.com/users/apache/events{/privacy}","received_events_url":"https://api.github.com/users/apache/received_events","type":"Organization","site_admin":false},"repo":{"id":52039373,"name":"incubator-openwhisk","full_name":"apache/incubator-openwhisk","owner":{"login":"apache","id":47359,"avatar_url":"https://avatars0.githubusercontent.com/u/47359?v=4","gravatar_id":"","url":"https://api.github.com/users/apache","html_url":"https://github.com/apache","followers_url":"https://api.github.com/users/apache/followers","following_url":"https://api.github.com/users/apache/following{/other_user}","gists_url":"https://api.github.com/users/apache/gists{/gist_id}","starred_url":"https://api.github.com/users/apache/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apache/subscriptions","organizations_url":"https://api.github.com/users/apache/orgs","repos_url":"https://api.github.com/users/apache/repos","events_url":"https://api.github.com/users/apache/events{/privacy}","received_events_url":"https://api.github.com/users/apache/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/apache/incubator-openwhisk","description":"Apache OpenWhisk is a serverless event-based programming service and an Apache Incubator project.","fork":false,"url":"https://api.github.com/repos/apache/incubator-openwhisk","forks_url":"https://api.github.com/repos/apache/incubator-openwhisk/forks","keys_url":"https://api.github.com/repos/apache/incubator-openwhisk/keys{/key_id}","collaborators_url":"https://api.github.com/repos/apache/incubator-openwhisk/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/apache/incubator-openwhisk/teams","hooks_url":"https://api.github.com/repos/apache/incubator-openwhisk/hooks","issue_events_url":"https://api.github.com/repos/apache/incubator-openwhisk/issues/events{/number}","events_url":"https://api.github.com/repos/apache/incubator-openwhisk/events","assignees_url":"https://api.github.com/repos/apache/incubator-openwhisk/assignees{/user}","branches_url":"https://api.github.com/repos/apache/incubator-openwhisk/branches{/branch}","tags_url":"https://api.github.com/repos/apache/incubator-openwhisk/tags","blobs_url":"https://api.github.com/repos/apache/incubator-openwhisk/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/apache/incubator-openwhisk/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/apache/incubator-openwhisk/git/refs{/sha}","trees_url":"https://api.github.com/repos/apache/incubator-openwhisk/git/trees{/sha}","statuses_url":"https://api.github.com/repos/apache/incubator-openwhisk/statuses/{sha}","languages_url":"https://api.github.com/repos/apache/incubator-openwhisk/languages","stargazers_url":"https://api.github.com/repos/apache/incubator-openwhisk/stargazers","contributors_url":"https://api.github.com/repos/apache/incubator-openwhisk/contributors","subscribers_url":"https://api.github.com/repos/apache/incubator-openwhisk/subscribers","subscription_url":"https://api.github.com/repos/apache/incubator-openwhisk/subscription","commits_url":"https://api.github.com/repos/apache/incubator-openwhisk/commits{/sha}","git_commits_url":"https://api.github.com/repos/apache/incubator-openwhisk/git/commits{/sha}","comments_url":"https://api.github.com/repos/apache/incubator-openwhisk/comments{/number}","issue_comment_url":"https://api.github.com/repos/apache/incubator-openwhisk/issues/comments{/number}","contents_url":"https://api.github.com/repos/apache/incubator-openwhisk/contents/{+path}","compare_url":"https://api.github.com/repos/apache/incubator-openwhisk/compare/{base}...{head}","merges_url":"https://api.github.com/repos/apache/incubator-openwhisk/merges","archive_url":"https://api.github.com/repos/apache/incubator-openwhisk/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/apache/incubator-openwhisk/downloads","issues_url":"https://api.github.com/repos/apache/incubator-openwhisk/issues{/number}","pulls_url":"https://api.github.com/repos/apache/incubator-openwhisk/pulls{/number}","milestones_url":"https://api.github.com/repos/apache/incubator-openwhisk/milestones{/number}","notifications_url":"https://api.github.com/repos/apache/incubator-openwhisk/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/apache/incubator-openwhisk/labels{/name}","releases_url":"https://api.github.com/repos/apache/incubator-openwhisk/releases{/id}","deployments_url":"https://api.github.com/repos/apache/incubator-openwhisk/deployments","created_at":"2016-02-18T21:16:19Z","updated_at":"2017-08-03T14:30:49Z","pushed_at":"2017-08-03T15:35:30Z","git_url":"git://github.com/apache/incubator-openwhisk.git","ssh_url":"git@github.com:apache/incubator-openwhisk.git","clone_url":"https://github.com/apache/incubator-openwhisk.git","svn_url":"https://github.com/apache/incubator-openwhisk","homepage":"http://openwhisk.org","size":56015,"stargazers_count":1775,"watchers_count":1775,"language":"Scala","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":390,"mirror_url":null,"open_issues_count":367,"forks":390,"open_issues":367,"watchers":1775,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/apache/incubator-openwhisk/pulls/2414"},"html":{"href":"https://github.com/apache/incubator-openwhisk/pull/2414"},"issue":{"href":"https://api.github.com/repos/apache/incubator-openwhisk/issues/2414"},"comments":{"href":"https://api.github.com/repos/apache/incubator-openwhisk/issues/2414/comments"},"review_comments":{"href":"https://api.github.com/repos/apache/incubator-openwhisk/pulls/2414/comments"},"review_comment":{"href":"https://api.github.com/repos/apache/incubator-openwhisk/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/apache/incubator-openwhisk/pulls/2414/commits"},"statuses":{"href":"https://api.github.com/repos/apache/incubator-openwhisk/statuses/6b404f5c34d59652ac4a77587bd668a96c8a770c"}}}}
{"actor":{"display_login":"tysonnorris"}}