{"action":"created","comment":{"url":"https://api.github.com/repos/twitter/bijection/pulls/comments/62915803","id":62915803,"diff_hunk":"@@ -0,0 +1,89 @@\n+/*\n+Copyright 2012 Twitter, Inc.\n+\n+Licensed under the Apache License, Version 2.0 (the \"License\");\n+you may not use this file except in compliance with the License.\n+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+package com.twitter.bijection.twitter_util\n+\n+import java.util.concurrent.{ Future => JFuture }\n+\n+import com.twitter.util._\n+\n+/**\n+ * Base class for converting java futures to twitter futures\n+ */\n+abstract class JavaFutureConverter {\n+  def apply[T](javaFuture: JFuture[T]): Future[T]\n+}\n+\n+/**\n+ * Converter based on the specified <code>futurePool</code> which will create one thread per\n+ * future possibly limited by the maximum size of the pool.\n+ * To favor if there aren't too many futures to convert and one cares about latency.\n+ * @param futurePool future pool used to retrieve the result of every future\n+ * @param mayInterruptIfRunning whether or not the initial java future can be interrupted if it's\n+ *                              running\n+ */\n+class FuturePoolJavaFutureConverter(\n+  futurePool: FuturePool,\n+  mayInterruptIfRunning: Boolean\n+) extends JavaFutureConverter {\n+  override def apply[T](javaFuture: JFuture[T]): Future[T] = {\n+    val f = futurePool { javaFuture.get() }\n+    val p = Promise.attached(f)\n+    p.setInterruptHandler { case NonFatal(e) =>\n+      if (p.detach()) {\n+        f.raise(e)\n+        javaFuture.cancel(mayInterruptIfRunning)\n+        p.setException(e)\n+      }\n+    }\n+    p\n+  }\n+}\n+\n+/**\n+ * Converter based on a [[Timer]] which will create a task which will check every\n+ * <code>checkFrequency</code> if the java future is completed, the threading model is the one\n+ * used by the specified <code>timer</code> which is often a thread pool of size 1.\n+ * To favor if there are a lot of futures to convert and one cares less about the latency induced\n+ * by <code>checkFrequency</code>.\n+ * <code>checkFrequency</code> needs to be a multiple of the timer implementation's granularity\n+ * which is often 1ms.\n+ * @param timer timer used to schedule a task which will check if the java future is done\n+ * @param checkFrequency frequency at which the java future will be checked for completion\n+ * @param mayInterruptIfRunning whether or not the initial java future can be interrupted if it's\n+ *                              running\n+ */\n+class TimerJavaFutureConverter(\n+  timer: Timer,\n+  checkFrequency: Duration,\n+  mayInterruptIfRunning: Boolean\n+) extends JavaFutureConverter {\n+  override def apply[T](javaFuture: JFuture[T]): Future[T] = {\n+    val p = Promise[T]\n+    val task = timer.schedule(checkFrequency) {\n+      if (javaFuture.isDone) {\n+        p.updateIfEmpty(Try(javaFuture.get()))","path":"bijection-util/src/main/scala/com/twitter/bijection/twitter_util/JavaFutureConverter.scala","position":78,"original_position":78,"commit_id":"4ba88b4c3c70e92aeccc3cbd4c646c162b87a566","original_commit_id":"5cfd3f5fa331bee414b83e80f8e1c192fdc29f64","user":{"login":"BenFradet","id":1737211,"avatar_url":"https://avatars.githubusercontent.com/u/1737211?v=3","gravatar_id":"","url":"https://api.github.com/users/BenFradet","html_url":"https://github.com/BenFradet","followers_url":"https://api.github.com/users/BenFradet/followers","following_url":"https://api.github.com/users/BenFradet/following{/other_user}","gists_url":"https://api.github.com/users/BenFradet/gists{/gist_id}","starred_url":"https://api.github.com/users/BenFradet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/BenFradet/subscriptions","organizations_url":"https://api.github.com/users/BenFradet/orgs","repos_url":"https://api.github.com/users/BenFradet/repos","events_url":"https://api.github.com/users/BenFradet/events{/privacy}","received_events_url":"https://api.github.com/users/BenFradet/received_events","type":"User","site_admin":false},"body":"indeed :'(","created_at":"2016-05-11T20:00:08Z","updated_at":"2016-05-11T20:00:08Z","html_url":"https://github.com/twitter/bijection/pull/247#discussion_r62915803","pull_request_url":"https://api.github.com/repos/twitter/bijection/pulls/247","_links":{"self":{"href":"https://api.github.com/repos/twitter/bijection/pulls/comments/62915803"},"html":{"href":"https://github.com/twitter/bijection/pull/247#discussion_r62915803"},"pull_request":{"href":"https://api.github.com/repos/twitter/bijection/pulls/247"}}},"pull_request":{"url":"https://api.github.com/repos/twitter/bijection/pulls/247","id":68753770,"html_url":"https://github.com/twitter/bijection/pull/247","diff_url":"https://github.com/twitter/bijection/pull/247.diff","patch_url":"https://github.com/twitter/bijection/pull/247.patch","issue_url":"https://api.github.com/repos/twitter/bijection/issues/247","number":247,"state":"open","locked":false,"title":"JavaFuture <=> TwitterFuture bijection","user":{"login":"BenFradet","id":1737211,"avatar_url":"https://avatars.githubusercontent.com/u/1737211?v=3","gravatar_id":"","url":"https://api.github.com/users/BenFradet","html_url":"https://github.com/BenFradet","followers_url":"https://api.github.com/users/BenFradet/followers","following_url":"https://api.github.com/users/BenFradet/following{/other_user}","gists_url":"https://api.github.com/users/BenFradet/gists{/gist_id}","starred_url":"https://api.github.com/users/BenFradet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/BenFradet/subscriptions","organizations_url":"https://api.github.com/users/BenFradet/orgs","repos_url":"https://api.github.com/users/BenFradet/repos","events_url":"https://api.github.com/users/BenFradet/events{/privacy}","received_events_url":"https://api.github.com/users/BenFradet/received_events","type":"User","site_admin":false},"body":"This implements a bijection between `JavaFuture`s and `TwitterFuture`s.\r\n\r\nIt originally came from [the storehaus-kafka module](https://github.com/twitter/storehaus/pull/286) because the kafka api uses `JavaFuture`.\r\n\r\nThe idea is to make it available here since it'd fit nicely with the other bijection between `ScalaFuture`s and `TwitterFuture`s.\r\n\r\ncredit to @johnynek for the implementation","created_at":"2016-05-03T18:38:16Z","updated_at":"2016-05-11T20:00:08Z","closed_at":null,"merged_at":null,"merge_commit_sha":"24b11dc1b80be0a557831a7c1a6d65cb2535d1fe","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/twitter/bijection/pulls/247/commits","review_comments_url":"https://api.github.com/repos/twitter/bijection/pulls/247/comments","review_comment_url":"https://api.github.com/repos/twitter/bijection/pulls/comments{/number}","comments_url":"https://api.github.com/repos/twitter/bijection/issues/247/comments","statuses_url":"https://api.github.com/repos/twitter/bijection/statuses/4ba88b4c3c70e92aeccc3cbd4c646c162b87a566","head":{"label":"BenFradet:java_future","ref":"java_future","sha":"4ba88b4c3c70e92aeccc3cbd4c646c162b87a566","user":{"login":"BenFradet","id":1737211,"avatar_url":"https://avatars.githubusercontent.com/u/1737211?v=3","gravatar_id":"","url":"https://api.github.com/users/BenFradet","html_url":"https://github.com/BenFradet","followers_url":"https://api.github.com/users/BenFradet/followers","following_url":"https://api.github.com/users/BenFradet/following{/other_user}","gists_url":"https://api.github.com/users/BenFradet/gists{/gist_id}","starred_url":"https://api.github.com/users/BenFradet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/BenFradet/subscriptions","organizations_url":"https://api.github.com/users/BenFradet/orgs","repos_url":"https://api.github.com/users/BenFradet/repos","events_url":"https://api.github.com/users/BenFradet/events{/privacy}","received_events_url":"https://api.github.com/users/BenFradet/received_events","type":"User","site_admin":false},"repo":{"id":56975055,"name":"bijection","full_name":"BenFradet/bijection","owner":{"login":"BenFradet","id":1737211,"avatar_url":"https://avatars.githubusercontent.com/u/1737211?v=3","gravatar_id":"","url":"https://api.github.com/users/BenFradet","html_url":"https://github.com/BenFradet","followers_url":"https://api.github.com/users/BenFradet/followers","following_url":"https://api.github.com/users/BenFradet/following{/other_user}","gists_url":"https://api.github.com/users/BenFradet/gists{/gist_id}","starred_url":"https://api.github.com/users/BenFradet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/BenFradet/subscriptions","organizations_url":"https://api.github.com/users/BenFradet/orgs","repos_url":"https://api.github.com/users/BenFradet/repos","events_url":"https://api.github.com/users/BenFradet/events{/privacy}","received_events_url":"https://api.github.com/users/BenFradet/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/BenFradet/bijection","description":"Reversible conversions between types","fork":true,"url":"https://api.github.com/repos/BenFradet/bijection","forks_url":"https://api.github.com/repos/BenFradet/bijection/forks","keys_url":"https://api.github.com/repos/BenFradet/bijection/keys{/key_id}","collaborators_url":"https://api.github.com/repos/BenFradet/bijection/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/BenFradet/bijection/teams","hooks_url":"https://api.github.com/repos/BenFradet/bijection/hooks","issue_events_url":"https://api.github.com/repos/BenFradet/bijection/issues/events{/number}","events_url":"https://api.github.com/repos/BenFradet/bijection/events","assignees_url":"https://api.github.com/repos/BenFradet/bijection/assignees{/user}","branches_url":"https://api.github.com/repos/BenFradet/bijection/branches{/branch}","tags_url":"https://api.github.com/repos/BenFradet/bijection/tags","blobs_url":"https://api.github.com/repos/BenFradet/bijection/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/BenFradet/bijection/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/BenFradet/bijection/git/refs{/sha}","trees_url":"https://api.github.com/repos/BenFradet/bijection/git/trees{/sha}","statuses_url":"https://api.github.com/repos/BenFradet/bijection/statuses/{sha}","languages_url":"https://api.github.com/repos/BenFradet/bijection/languages","stargazers_url":"https://api.github.com/repos/BenFradet/bijection/stargazers","contributors_url":"https://api.github.com/repos/BenFradet/bijection/contributors","subscribers_url":"https://api.github.com/repos/BenFradet/bijection/subscribers","subscription_url":"https://api.github.com/repos/BenFradet/bijection/subscription","commits_url":"https://api.github.com/repos/BenFradet/bijection/commits{/sha}","git_commits_url":"https://api.github.com/repos/BenFradet/bijection/git/commits{/sha}","comments_url":"https://api.github.com/repos/BenFradet/bijection/comments{/number}","issue_comment_url":"https://api.github.com/repos/BenFradet/bijection/issues/comments{/number}","contents_url":"https://api.github.com/repos/BenFradet/bijection/contents/{+path}","compare_url":"https://api.github.com/repos/BenFradet/bijection/compare/{base}...{head}","merges_url":"https://api.github.com/repos/BenFradet/bijection/merges","archive_url":"https://api.github.com/repos/BenFradet/bijection/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/BenFradet/bijection/downloads","issues_url":"https://api.github.com/repos/BenFradet/bijection/issues{/number}","pulls_url":"https://api.github.com/repos/BenFradet/bijection/pulls{/number}","milestones_url":"https://api.github.com/repos/BenFradet/bijection/milestones{/number}","notifications_url":"https://api.github.com/repos/BenFradet/bijection/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/BenFradet/bijection/labels{/name}","releases_url":"https://api.github.com/repos/BenFradet/bijection/releases{/id}","deployments_url":"https://api.github.com/repos/BenFradet/bijection/deployments","created_at":"2016-04-24T14:10:41Z","updated_at":"2016-04-24T14:10:42Z","pushed_at":"2016-05-10T20:54:17Z","git_url":"git://github.com/BenFradet/bijection.git","ssh_url":"git@github.com:BenFradet/bijection.git","clone_url":"https://github.com/BenFradet/bijection.git","svn_url":"https://github.com/BenFradet/bijection","homepage":"","size":2000,"stargazers_count":0,"watchers_count":0,"language":"Scala","has_issues":false,"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":"develop"}},"base":{"label":"twitter:develop","ref":"develop","sha":"2019fcd7c31a2a02782c9875953199555f28811e","user":{"login":"twitter","id":50278,"avatar_url":"https://avatars.githubusercontent.com/u/50278?v=3","gravatar_id":"","url":"https://api.github.com/users/twitter","html_url":"https://github.com/twitter","followers_url":"https://api.github.com/users/twitter/followers","following_url":"https://api.github.com/users/twitter/following{/other_user}","gists_url":"https://api.github.com/users/twitter/gists{/gist_id}","starred_url":"https://api.github.com/users/twitter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/twitter/subscriptions","organizations_url":"https://api.github.com/users/twitter/orgs","repos_url":"https://api.github.com/users/twitter/repos","events_url":"https://api.github.com/users/twitter/events{/privacy}","received_events_url":"https://api.github.com/users/twitter/received_events","type":"Organization","site_admin":false},"repo":{"id":7380994,"name":"bijection","full_name":"twitter/bijection","owner":{"login":"twitter","id":50278,"avatar_url":"https://avatars.githubusercontent.com/u/50278?v=3","gravatar_id":"","url":"https://api.github.com/users/twitter","html_url":"https://github.com/twitter","followers_url":"https://api.github.com/users/twitter/followers","following_url":"https://api.github.com/users/twitter/following{/other_user}","gists_url":"https://api.github.com/users/twitter/gists{/gist_id}","starred_url":"https://api.github.com/users/twitter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/twitter/subscriptions","organizations_url":"https://api.github.com/users/twitter/orgs","repos_url":"https://api.github.com/users/twitter/repos","events_url":"https://api.github.com/users/twitter/events{/privacy}","received_events_url":"https://api.github.com/users/twitter/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/twitter/bijection","description":"Reversible conversions between types","fork":false,"url":"https://api.github.com/repos/twitter/bijection","forks_url":"https://api.github.com/repos/twitter/bijection/forks","keys_url":"https://api.github.com/repos/twitter/bijection/keys{/key_id}","collaborators_url":"https://api.github.com/repos/twitter/bijection/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/twitter/bijection/teams","hooks_url":"https://api.github.com/repos/twitter/bijection/hooks","issue_events_url":"https://api.github.com/repos/twitter/bijection/issues/events{/number}","events_url":"https://api.github.com/repos/twitter/bijection/events","assignees_url":"https://api.github.com/repos/twitter/bijection/assignees{/user}","branches_url":"https://api.github.com/repos/twitter/bijection/branches{/branch}","tags_url":"https://api.github.com/repos/twitter/bijection/tags","blobs_url":"https://api.github.com/repos/twitter/bijection/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/twitter/bijection/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/twitter/bijection/git/refs{/sha}","trees_url":"https://api.github.com/repos/twitter/bijection/git/trees{/sha}","statuses_url":"https://api.github.com/repos/twitter/bijection/statuses/{sha}","languages_url":"https://api.github.com/repos/twitter/bijection/languages","stargazers_url":"https://api.github.com/repos/twitter/bijection/stargazers","contributors_url":"https://api.github.com/repos/twitter/bijection/contributors","subscribers_url":"https://api.github.com/repos/twitter/bijection/subscribers","subscription_url":"https://api.github.com/repos/twitter/bijection/subscription","commits_url":"https://api.github.com/repos/twitter/bijection/commits{/sha}","git_commits_url":"https://api.github.com/repos/twitter/bijection/git/commits{/sha}","comments_url":"https://api.github.com/repos/twitter/bijection/comments{/number}","issue_comment_url":"https://api.github.com/repos/twitter/bijection/issues/comments{/number}","contents_url":"https://api.github.com/repos/twitter/bijection/contents/{+path}","compare_url":"https://api.github.com/repos/twitter/bijection/compare/{base}...{head}","merges_url":"https://api.github.com/repos/twitter/bijection/merges","archive_url":"https://api.github.com/repos/twitter/bijection/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/twitter/bijection/downloads","issues_url":"https://api.github.com/repos/twitter/bijection/issues{/number}","pulls_url":"https://api.github.com/repos/twitter/bijection/pulls{/number}","milestones_url":"https://api.github.com/repos/twitter/bijection/milestones{/number}","notifications_url":"https://api.github.com/repos/twitter/bijection/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/twitter/bijection/labels{/name}","releases_url":"https://api.github.com/repos/twitter/bijection/releases{/id}","deployments_url":"https://api.github.com/repos/twitter/bijection/deployments","created_at":"2012-12-30T22:22:25Z","updated_at":"2016-05-11T17:15:24Z","pushed_at":"2016-05-10T20:54:17Z","git_url":"git://github.com/twitter/bijection.git","ssh_url":"git@github.com:twitter/bijection.git","clone_url":"https://github.com/twitter/bijection.git","svn_url":"https://github.com/twitter/bijection","homepage":"","size":2253,"stargazers_count":382,"watchers_count":382,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":75,"mirror_url":null,"open_issues_count":26,"forks":75,"open_issues":26,"watchers":382,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/twitter/bijection/pulls/247"},"html":{"href":"https://github.com/twitter/bijection/pull/247"},"issue":{"href":"https://api.github.com/repos/twitter/bijection/issues/247"},"comments":{"href":"https://api.github.com/repos/twitter/bijection/issues/247/comments"},"review_comments":{"href":"https://api.github.com/repos/twitter/bijection/pulls/247/comments"},"review_comment":{"href":"https://api.github.com/repos/twitter/bijection/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/twitter/bijection/pulls/247/commits"},"statuses":{"href":"https://api.github.com/repos/twitter/bijection/statuses/4ba88b4c3c70e92aeccc3cbd4c646c162b87a566"}}}}