{"action":"created","comment":{"url":"https://api.github.com/repos/storm-enroute/coroutines/pulls/comments/72191116","id":72191116,"diff_hunk":"@@ -0,0 +1,104 @@\n+package org.coroutines.extra\n+\n+\n+\n+import org.coroutines._\n+import scala.annotation.unchecked.uncheckedVariance\n+import scala.concurrent.ExecutionContext.Implicits.global\n+import scala.concurrent._\n+import scala.language.experimental.macros\n+import scala.reflect.macros.whitebox.Context\n+import scala.util.{ Success, Failure }\n+\n+\n+\n+object AsyncAwait {\n+  /** Await the result of a future.\n+   *\n+   *  When called inside an `async` body, this function will block until its\n+   *  associated future completes.\n+   *\n+   *  @return A coroutine that yields a tuple. `async` will assign this tuple's\n+   *          second element to hold the completed result of the `Future` passed\n+   *          into the coroutine. The coroutine will directly return the\n+   *          result of the future.\n+   */\n+  def await[R]: Future[R] ~~> (Future[R], R) =\n+    coroutine { (awaitedFuture: Future[R]) =>\n+      yieldval(awaitedFuture)\n+      var result: R = null.asInstanceOf[R]\n+      awaitedFuture.value match {\n+        case Some(Success(x)) => result = x\n+        case Some(Failure(error)) => throw error\n+        case None => sys.error(\"Future was not completed\")\n+      }\n+      result\n+    }\n+\n+  /** Calls `body`, blocking on any calls to `await`.\n+   *\n+   *  @param body  A coroutine to be invoked.\n+   *  @return      A `Future` wrapping the result of the coroutine. The future fails\n+   *               if `body` throws an exception or one of the `await`s takes a failed\n+   *               future.\n+   */\n+  def asyncCall[Y, R](body: ~~~>[Future[Y], R]): Future[R] = {\n+    val c = call(body())\n+    val p = Promise[R]\n+    def loop() {\n+      if (!c.resume) {\n+        c.tryResult match {\n+          case Success(result) => p.success(result)\n+          case Failure(exception) => p.failure(exception)\n+        }\n+      } else {\n+        val awaitedFuture = c.value\n+        if (awaitedFuture.isCompleted) {\n+          awaitedFuture.value match {\n+            case Some(Success(result)) =>\n+              loop()\n+            case Some(Failure(exception)) =>","path":"coroutines-extra/src/main/scala/org/coroutines/extra/AsyncAwait.scala","position":60,"original_position":60,"commit_id":"7fa77135d81c355bbee0121ada494bda88babb0f","original_commit_id":"7fa77135d81c355bbee0121ada494bda88babb0f","user":{"login":"smithjessk","id":5957838,"avatar_url":"https://avatars.githubusercontent.com/u/5957838?v=3","gravatar_id":"","url":"https://api.github.com/users/smithjessk","html_url":"https://github.com/smithjessk","followers_url":"https://api.github.com/users/smithjessk/followers","following_url":"https://api.github.com/users/smithjessk/following{/other_user}","gists_url":"https://api.github.com/users/smithjessk/gists{/gist_id}","starred_url":"https://api.github.com/users/smithjessk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/smithjessk/subscriptions","organizations_url":"https://api.github.com/users/smithjessk/orgs","repos_url":"https://api.github.com/users/smithjessk/repos","events_url":"https://api.github.com/users/smithjessk/events{/privacy}","received_events_url":"https://api.github.com/users/smithjessk/received_events","type":"User","site_admin":false},"body":"I think I'm misinterpreting the test you're describing because, as of 7fa77135d81c355bbee0121ada494bda88babb0f, this passes:\r\n\r\n```scala\r\ntest(\"await should bubble up exceptions\") {\r\n  def thrower() = {\r\n    throw new TestException\r\n    Future(1)\r\n  }\r\n\r\n  var exceptionFound = false\r\n  val future = async {\r\n    try {\r\n      await(thrower())\r\n      ()\r\n    } catch {\r\n      case _: TestException => exceptionFound = true\r\n    }\r\n  }\r\n  val r = Await.result(future, 1 seconds)\r\n  assert(exceptionFound)\r\n}\r\n```","created_at":"2016-07-26T05:49:33Z","updated_at":"2016-07-26T05:49:33Z","html_url":"https://github.com/storm-enroute/coroutines/pull/23#discussion_r72191116","pull_request_url":"https://api.github.com/repos/storm-enroute/coroutines/pulls/23","_links":{"self":{"href":"https://api.github.com/repos/storm-enroute/coroutines/pulls/comments/72191116"},"html":{"href":"https://github.com/storm-enroute/coroutines/pull/23#discussion_r72191116"},"pull_request":{"href":"https://api.github.com/repos/storm-enroute/coroutines/pulls/23"}}},"pull_request":{"url":"https://api.github.com/repos/storm-enroute/coroutines/pulls/23","id":74827360,"html_url":"https://github.com/storm-enroute/coroutines/pull/23","diff_url":"https://github.com/storm-enroute/coroutines/pull/23.diff","patch_url":"https://github.com/storm-enroute/coroutines/pull/23.patch","issue_url":"https://api.github.com/repos/storm-enroute/coroutines/issues/23","number":23,"state":"open","locked":false,"title":"Implement async, document Instance methods","user":{"login":"smithjessk","id":5957838,"avatar_url":"https://avatars.githubusercontent.com/u/5957838?v=3","gravatar_id":"","url":"https://api.github.com/users/smithjessk","html_url":"https://github.com/smithjessk","followers_url":"https://api.github.com/users/smithjessk/followers","following_url":"https://api.github.com/users/smithjessk/following{/other_user}","gists_url":"https://api.github.com/users/smithjessk/gists{/gist_id}","starred_url":"https://api.github.com/users/smithjessk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/smithjessk/subscriptions","organizations_url":"https://api.github.com/users/smithjessk/orgs","repos_url":"https://api.github.com/users/smithjessk/repos","events_url":"https://api.github.com/users/smithjessk/events{/privacy}","received_events_url":"https://api.github.com/users/smithjessk/received_events","type":"User","site_admin":false},"body":"- Add a new subproject, `coroutines-extra`. This subproject will contain future utilities for Coroutines such as enumerators and continuations\r\n- Implement Async/Await. This implementation was inspired by the one present in the  [examples directory](https://github.com/storm-enroute/coroutines/blob/a7420fa5bd46eb76ebeb6b86fb7676940fcb9a64/src/test/scala/org/examples/AsyncAwait.scala). \r\n- Document more methods on `Coroutine.Instance`\r\n\r\nIf you'd prefer, I can split this PR into one for the implementation and one for the documentation.","created_at":"2016-06-22T17:48:27Z","updated_at":"2016-07-26T05:49:33Z","closed_at":null,"merged_at":null,"merge_commit_sha":"0aebf761ba8ca80a4d3e686ac218bc395e626a63","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/storm-enroute/coroutines/pulls/23/commits","review_comments_url":"https://api.github.com/repos/storm-enroute/coroutines/pulls/23/comments","review_comment_url":"https://api.github.com/repos/storm-enroute/coroutines/pulls/comments{/number}","comments_url":"https://api.github.com/repos/storm-enroute/coroutines/issues/23/comments","statuses_url":"https://api.github.com/repos/storm-enroute/coroutines/statuses/7fa77135d81c355bbee0121ada494bda88babb0f","head":{"label":"smithjessk:implement-async","ref":"implement-async","sha":"7fa77135d81c355bbee0121ada494bda88babb0f","user":{"login":"smithjessk","id":5957838,"avatar_url":"https://avatars.githubusercontent.com/u/5957838?v=3","gravatar_id":"","url":"https://api.github.com/users/smithjessk","html_url":"https://github.com/smithjessk","followers_url":"https://api.github.com/users/smithjessk/followers","following_url":"https://api.github.com/users/smithjessk/following{/other_user}","gists_url":"https://api.github.com/users/smithjessk/gists{/gist_id}","starred_url":"https://api.github.com/users/smithjessk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/smithjessk/subscriptions","organizations_url":"https://api.github.com/users/smithjessk/orgs","repos_url":"https://api.github.com/users/smithjessk/repos","events_url":"https://api.github.com/users/smithjessk/events{/privacy}","received_events_url":"https://api.github.com/users/smithjessk/received_events","type":"User","site_admin":false},"repo":{"id":59436743,"name":"coroutines","full_name":"smithjessk/coroutines","owner":{"login":"smithjessk","id":5957838,"avatar_url":"https://avatars.githubusercontent.com/u/5957838?v=3","gravatar_id":"","url":"https://api.github.com/users/smithjessk","html_url":"https://github.com/smithjessk","followers_url":"https://api.github.com/users/smithjessk/followers","following_url":"https://api.github.com/users/smithjessk/following{/other_user}","gists_url":"https://api.github.com/users/smithjessk/gists{/gist_id}","starred_url":"https://api.github.com/users/smithjessk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/smithjessk/subscriptions","organizations_url":"https://api.github.com/users/smithjessk/orgs","repos_url":"https://api.github.com/users/smithjessk/repos","events_url":"https://api.github.com/users/smithjessk/events{/privacy}","received_events_url":"https://api.github.com/users/smithjessk/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/smithjessk/coroutines","description":"Scala coroutines implementation.","fork":true,"url":"https://api.github.com/repos/smithjessk/coroutines","forks_url":"https://api.github.com/repos/smithjessk/coroutines/forks","keys_url":"https://api.github.com/repos/smithjessk/coroutines/keys{/key_id}","collaborators_url":"https://api.github.com/repos/smithjessk/coroutines/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/smithjessk/coroutines/teams","hooks_url":"https://api.github.com/repos/smithjessk/coroutines/hooks","issue_events_url":"https://api.github.com/repos/smithjessk/coroutines/issues/events{/number}","events_url":"https://api.github.com/repos/smithjessk/coroutines/events","assignees_url":"https://api.github.com/repos/smithjessk/coroutines/assignees{/user}","branches_url":"https://api.github.com/repos/smithjessk/coroutines/branches{/branch}","tags_url":"https://api.github.com/repos/smithjessk/coroutines/tags","blobs_url":"https://api.github.com/repos/smithjessk/coroutines/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/smithjessk/coroutines/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/smithjessk/coroutines/git/refs{/sha}","trees_url":"https://api.github.com/repos/smithjessk/coroutines/git/trees{/sha}","statuses_url":"https://api.github.com/repos/smithjessk/coroutines/statuses/{sha}","languages_url":"https://api.github.com/repos/smithjessk/coroutines/languages","stargazers_url":"https://api.github.com/repos/smithjessk/coroutines/stargazers","contributors_url":"https://api.github.com/repos/smithjessk/coroutines/contributors","subscribers_url":"https://api.github.com/repos/smithjessk/coroutines/subscribers","subscription_url":"https://api.github.com/repos/smithjessk/coroutines/subscription","commits_url":"https://api.github.com/repos/smithjessk/coroutines/commits{/sha}","git_commits_url":"https://api.github.com/repos/smithjessk/coroutines/git/commits{/sha}","comments_url":"https://api.github.com/repos/smithjessk/coroutines/comments{/number}","issue_comment_url":"https://api.github.com/repos/smithjessk/coroutines/issues/comments{/number}","contents_url":"https://api.github.com/repos/smithjessk/coroutines/contents/{+path}","compare_url":"https://api.github.com/repos/smithjessk/coroutines/compare/{base}...{head}","merges_url":"https://api.github.com/repos/smithjessk/coroutines/merges","archive_url":"https://api.github.com/repos/smithjessk/coroutines/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/smithjessk/coroutines/downloads","issues_url":"https://api.github.com/repos/smithjessk/coroutines/issues{/number}","pulls_url":"https://api.github.com/repos/smithjessk/coroutines/pulls{/number}","milestones_url":"https://api.github.com/repos/smithjessk/coroutines/milestones{/number}","notifications_url":"https://api.github.com/repos/smithjessk/coroutines/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/smithjessk/coroutines/labels{/name}","releases_url":"https://api.github.com/repos/smithjessk/coroutines/releases{/id}","deployments_url":"https://api.github.com/repos/smithjessk/coroutines/deployments","created_at":"2016-05-22T22:11:34Z","updated_at":"2016-05-22T22:11:36Z","pushed_at":"2016-07-13T20:51:51Z","git_url":"git://github.com/smithjessk/coroutines.git","ssh_url":"git@github.com:smithjessk/coroutines.git","clone_url":"https://github.com/smithjessk/coroutines.git","svn_url":"https://github.com/smithjessk/coroutines","homepage":"http://storm-enroute.com/coroutines","size":673,"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":"master"}},"base":{"label":"storm-enroute:master","ref":"master","sha":"a7420fa5bd46eb76ebeb6b86fb7676940fcb9a64","user":{"login":"storm-enroute","id":5874628,"avatar_url":"https://avatars.githubusercontent.com/u/5874628?v=3","gravatar_id":"","url":"https://api.github.com/users/storm-enroute","html_url":"https://github.com/storm-enroute","followers_url":"https://api.github.com/users/storm-enroute/followers","following_url":"https://api.github.com/users/storm-enroute/following{/other_user}","gists_url":"https://api.github.com/users/storm-enroute/gists{/gist_id}","starred_url":"https://api.github.com/users/storm-enroute/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/storm-enroute/subscriptions","organizations_url":"https://api.github.com/users/storm-enroute/orgs","repos_url":"https://api.github.com/users/storm-enroute/repos","events_url":"https://api.github.com/users/storm-enroute/events{/privacy}","received_events_url":"https://api.github.com/users/storm-enroute/received_events","type":"Organization","site_admin":false},"repo":{"id":46452427,"name":"coroutines","full_name":"storm-enroute/coroutines","owner":{"login":"storm-enroute","id":5874628,"avatar_url":"https://avatars.githubusercontent.com/u/5874628?v=3","gravatar_id":"","url":"https://api.github.com/users/storm-enroute","html_url":"https://github.com/storm-enroute","followers_url":"https://api.github.com/users/storm-enroute/followers","following_url":"https://api.github.com/users/storm-enroute/following{/other_user}","gists_url":"https://api.github.com/users/storm-enroute/gists{/gist_id}","starred_url":"https://api.github.com/users/storm-enroute/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/storm-enroute/subscriptions","organizations_url":"https://api.github.com/users/storm-enroute/orgs","repos_url":"https://api.github.com/users/storm-enroute/repos","events_url":"https://api.github.com/users/storm-enroute/events{/privacy}","received_events_url":"https://api.github.com/users/storm-enroute/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/storm-enroute/coroutines","description":"Scala coroutines implementation.","fork":false,"url":"https://api.github.com/repos/storm-enroute/coroutines","forks_url":"https://api.github.com/repos/storm-enroute/coroutines/forks","keys_url":"https://api.github.com/repos/storm-enroute/coroutines/keys{/key_id}","collaborators_url":"https://api.github.com/repos/storm-enroute/coroutines/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/storm-enroute/coroutines/teams","hooks_url":"https://api.github.com/repos/storm-enroute/coroutines/hooks","issue_events_url":"https://api.github.com/repos/storm-enroute/coroutines/issues/events{/number}","events_url":"https://api.github.com/repos/storm-enroute/coroutines/events","assignees_url":"https://api.github.com/repos/storm-enroute/coroutines/assignees{/user}","branches_url":"https://api.github.com/repos/storm-enroute/coroutines/branches{/branch}","tags_url":"https://api.github.com/repos/storm-enroute/coroutines/tags","blobs_url":"https://api.github.com/repos/storm-enroute/coroutines/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/storm-enroute/coroutines/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/storm-enroute/coroutines/git/refs{/sha}","trees_url":"https://api.github.com/repos/storm-enroute/coroutines/git/trees{/sha}","statuses_url":"https://api.github.com/repos/storm-enroute/coroutines/statuses/{sha}","languages_url":"https://api.github.com/repos/storm-enroute/coroutines/languages","stargazers_url":"https://api.github.com/repos/storm-enroute/coroutines/stargazers","contributors_url":"https://api.github.com/repos/storm-enroute/coroutines/contributors","subscribers_url":"https://api.github.com/repos/storm-enroute/coroutines/subscribers","subscription_url":"https://api.github.com/repos/storm-enroute/coroutines/subscription","commits_url":"https://api.github.com/repos/storm-enroute/coroutines/commits{/sha}","git_commits_url":"https://api.github.com/repos/storm-enroute/coroutines/git/commits{/sha}","comments_url":"https://api.github.com/repos/storm-enroute/coroutines/comments{/number}","issue_comment_url":"https://api.github.com/repos/storm-enroute/coroutines/issues/comments{/number}","contents_url":"https://api.github.com/repos/storm-enroute/coroutines/contents/{+path}","compare_url":"https://api.github.com/repos/storm-enroute/coroutines/compare/{base}...{head}","merges_url":"https://api.github.com/repos/storm-enroute/coroutines/merges","archive_url":"https://api.github.com/repos/storm-enroute/coroutines/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/storm-enroute/coroutines/downloads","issues_url":"https://api.github.com/repos/storm-enroute/coroutines/issues{/number}","pulls_url":"https://api.github.com/repos/storm-enroute/coroutines/pulls{/number}","milestones_url":"https://api.github.com/repos/storm-enroute/coroutines/milestones{/number}","notifications_url":"https://api.github.com/repos/storm-enroute/coroutines/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/storm-enroute/coroutines/labels{/name}","releases_url":"https://api.github.com/repos/storm-enroute/coroutines/releases{/id}","deployments_url":"https://api.github.com/repos/storm-enroute/coroutines/deployments","created_at":"2015-11-18T22:44:40Z","updated_at":"2016-07-24T07:22:24Z","pushed_at":"2016-07-12T15:35:15Z","git_url":"git://github.com/storm-enroute/coroutines.git","ssh_url":"git@github.com:storm-enroute/coroutines.git","clone_url":"https://github.com/storm-enroute/coroutines.git","svn_url":"https://github.com/storm-enroute/coroutines","homepage":"http://storm-enroute.com/coroutines","size":612,"stargazers_count":99,"watchers_count":99,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":8,"mirror_url":null,"open_issues_count":9,"forks":8,"open_issues":9,"watchers":99,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/storm-enroute/coroutines/pulls/23"},"html":{"href":"https://github.com/storm-enroute/coroutines/pull/23"},"issue":{"href":"https://api.github.com/repos/storm-enroute/coroutines/issues/23"},"comments":{"href":"https://api.github.com/repos/storm-enroute/coroutines/issues/23/comments"},"review_comments":{"href":"https://api.github.com/repos/storm-enroute/coroutines/pulls/23/comments"},"review_comment":{"href":"https://api.github.com/repos/storm-enroute/coroutines/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/storm-enroute/coroutines/pulls/23/commits"},"statuses":{"href":"https://api.github.com/repos/storm-enroute/coroutines/statuses/7fa77135d81c355bbee0121ada494bda88babb0f"}}}}
{"actor":{"display_login":"smithjessk"}}