{"action":"created","comment":{"url":"https://api.github.com/repos/akka/akka/pulls/comments/128405985","pull_request_review_id":50917370,"id":128405985,"diff_hunk":"@@ -101,4 +101,39 @@ Java\n :   @@snip [IntegrationDocTest.java]($code$/java/jdocs/stream/IntegrationDocTest.java) { #email-addresses-mapAsync-supervision }\n \n If we would not use `Resume` the default stopping strategy would complete the stream\n-with failure on the first @scala[`Future`] @java[`CompletionStage`] that was completed @scala[with `Failure`]@java[exceptionally].\n\\ No newline at end of file\n+with failure on the first @scala[`Future`] @java[`CompletionStage`] that was completed @scala[with `Failure`]@java[exceptionally].\n+\n+## Delayed restarts with a backoff stage\n+\n+Just as Akka provides the @ref:[backoff supervision pattern for actors](../general/supervision.md#backoff-supervisor), Akka streams\n+also provides a `RestartSource`, `RestartSink` and `RestartFlow` for implementing the so-called *exponential backoff \n+supervision strategy*, starting a stage again when it fails, each time with a growing time delay between restarts.\n+\n+This pattern is useful when the stage fails <a id=\"^1\" href=\"#1\">[1]</a> because some external resource is not available,\n+and we need to give it some time to start-up again. One of the prime examples when this is useful is\n+when a WebSocket connection fails due to the HTTP server it's running on going down, perhaps because it is overloaded. \n+By using an exponential backoff, we avoid going into a tight reconnect look, which both gives the HTTP server some time\n+to recover, and it avoids using needless resources on the client side.\n+\n+> <a id=\"1\" href=\"#^1\">[1]</a> A failure can be indicated in two different ways; by the stream completing or failing.\n+\n+The following snippet shows how to create a backoff supervisor using `akka.stream.scaladsl.RestartSource`\n+which will supervise the given `Source`. The `Source` in this case is a stream of Server Sent Events, \n+produced by akka-http. If the stream fails at any point, the request will be made again, in increasing \n+intervals of 3, 6, 12, 24 and finally 30 seconds:","path":"akka-docs/src/main/paradox/scala/stream/stream-error.md","position":25,"original_position":25,"commit_id":"5d8a367a6bff39672f1aee9810695c33623adf70","original_commit_id":"5d8a367a6bff39672f1aee9810695c33623adf70","user":{"login":"ktoso","id":120979,"avatar_url":"https://avatars1.githubusercontent.com/u/120979?v=4","gravatar_id":"","url":"https://api.github.com/users/ktoso","html_url":"https://github.com/ktoso","followers_url":"https://api.github.com/users/ktoso/followers","following_url":"https://api.github.com/users/ktoso/following{/other_user}","gists_url":"https://api.github.com/users/ktoso/gists{/gist_id}","starred_url":"https://api.github.com/users/ktoso/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ktoso/subscriptions","organizations_url":"https://api.github.com/users/ktoso/orgs","repos_url":"https://api.github.com/users/ktoso/repos","events_url":"https://api.github.com/users/ktoso/events{/privacy}","received_events_url":"https://api.github.com/users/ktoso/received_events","type":"User","site_admin":false},"body":"`finally 30 seconds (at which it will remain capped due to the maxBackoff parameter)`","created_at":"2017-07-20T01:14:55Z","updated_at":"2017-07-20T01:16:25Z","html_url":"https://github.com/akka/akka/pull/23367#discussion_r128405985","pull_request_url":"https://api.github.com/repos/akka/akka/pulls/23367","_links":{"self":{"href":"https://api.github.com/repos/akka/akka/pulls/comments/128405985"},"html":{"href":"https://github.com/akka/akka/pull/23367#discussion_r128405985"},"pull_request":{"href":"https://api.github.com/repos/akka/akka/pulls/23367"}}},"pull_request":{"url":"https://api.github.com/repos/akka/akka/pulls/23367","id":130718126,"html_url":"https://github.com/akka/akka/pull/23367","diff_url":"https://github.com/akka/akka/pull/23367.diff","patch_url":"https://github.com/akka/akka/pull/23367.patch","issue_url":"https://api.github.com/repos/akka/akka/issues/23367","number":23367,"state":"open","locked":false,"title":"Restart Flow/Source/Sink","user":{"login":"jroper","id":105833,"avatar_url":"https://avatars0.githubusercontent.com/u/105833?v=4","gravatar_id":"","url":"https://api.github.com/users/jroper","html_url":"https://github.com/jroper","followers_url":"https://api.github.com/users/jroper/followers","following_url":"https://api.github.com/users/jroper/following{/other_user}","gists_url":"https://api.github.com/users/jroper/gists{/gist_id}","starred_url":"https://api.github.com/users/jroper/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jroper/subscriptions","organizations_url":"https://api.github.com/users/jroper/orgs","repos_url":"https://api.github.com/users/jroper/repos","events_url":"https://api.github.com/users/jroper/events{/privacy}","received_events_url":"https://api.github.com/users/jroper/received_events","type":"User","site_admin":false},"body":"See https://github.com/akka/akka/issues/19950#issuecomment-315240206 for context.\r\n\r\nOne major change from the API proposed is that this wraps factories of sources/flows/sinks, not plain sources/flows/sinks.\r\n\r\nI did this basically because there's no equivalent of `Flow.apply(() => Flow)` (for Source there's lazily and for Sink there's lazyInit). Why this is important is because very often you start with a graph that is not reusable, a perfect use case for a restartable flow is where you want to feed the stream through a WebSocket using for example `Http().webSocketClientFlow(WebSocketRequest(\"ws://echo.websocket.org\"))`. But that WebSocket flow is not reusable, a second attempt to materialize it will fail. Hence, we need a factory of flows to be able to use the API in this way.\r\n\r\nSince the flow version was taking a factory, I thought the source and sink version should also take a factory for consistency. And besides, neither `Source.lazily` nor `Sink.lazyInit` actually provides the semantics of just turning a factory into the direct instance, they also delay the invocation until first pull/push, which is subtley but not insignificantly different.","created_at":"2017-07-15T14:44:32Z","updated_at":"2017-07-20T01:16:25Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c75f4c9594aac7ad65209619c2ab1673695bc217","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/akka/akka/pulls/23367/commits","review_comments_url":"https://api.github.com/repos/akka/akka/pulls/23367/comments","review_comment_url":"https://api.github.com/repos/akka/akka/pulls/comments{/number}","comments_url":"https://api.github.com/repos/akka/akka/issues/23367/comments","statuses_url":"https://api.github.com/repos/akka/akka/statuses/5d8a367a6bff39672f1aee9810695c33623adf70","head":{"label":"jroper:restartsourceflowsink","ref":"restartsourceflowsink","sha":"5d8a367a6bff39672f1aee9810695c33623adf70","user":{"login":"jroper","id":105833,"avatar_url":"https://avatars0.githubusercontent.com/u/105833?v=4","gravatar_id":"","url":"https://api.github.com/users/jroper","html_url":"https://github.com/jroper","followers_url":"https://api.github.com/users/jroper/followers","following_url":"https://api.github.com/users/jroper/following{/other_user}","gists_url":"https://api.github.com/users/jroper/gists{/gist_id}","starred_url":"https://api.github.com/users/jroper/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jroper/subscriptions","organizations_url":"https://api.github.com/users/jroper/orgs","repos_url":"https://api.github.com/users/jroper/repos","events_url":"https://api.github.com/users/jroper/events{/privacy}","received_events_url":"https://api.github.com/users/jroper/received_events","type":"User","site_admin":false},"repo":{"id":41785585,"name":"akka","full_name":"jroper/akka","owner":{"login":"jroper","id":105833,"avatar_url":"https://avatars0.githubusercontent.com/u/105833?v=4","gravatar_id":"","url":"https://api.github.com/users/jroper","html_url":"https://github.com/jroper","followers_url":"https://api.github.com/users/jroper/followers","following_url":"https://api.github.com/users/jroper/following{/other_user}","gists_url":"https://api.github.com/users/jroper/gists{/gist_id}","starred_url":"https://api.github.com/users/jroper/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jroper/subscriptions","organizations_url":"https://api.github.com/users/jroper/orgs","repos_url":"https://api.github.com/users/jroper/repos","events_url":"https://api.github.com/users/jroper/events{/privacy}","received_events_url":"https://api.github.com/users/jroper/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jroper/akka","description":"Akka Project","fork":true,"url":"https://api.github.com/repos/jroper/akka","forks_url":"https://api.github.com/repos/jroper/akka/forks","keys_url":"https://api.github.com/repos/jroper/akka/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jroper/akka/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jroper/akka/teams","hooks_url":"https://api.github.com/repos/jroper/akka/hooks","issue_events_url":"https://api.github.com/repos/jroper/akka/issues/events{/number}","events_url":"https://api.github.com/repos/jroper/akka/events","assignees_url":"https://api.github.com/repos/jroper/akka/assignees{/user}","branches_url":"https://api.github.com/repos/jroper/akka/branches{/branch}","tags_url":"https://api.github.com/repos/jroper/akka/tags","blobs_url":"https://api.github.com/repos/jroper/akka/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jroper/akka/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jroper/akka/git/refs{/sha}","trees_url":"https://api.github.com/repos/jroper/akka/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jroper/akka/statuses/{sha}","languages_url":"https://api.github.com/repos/jroper/akka/languages","stargazers_url":"https://api.github.com/repos/jroper/akka/stargazers","contributors_url":"https://api.github.com/repos/jroper/akka/contributors","subscribers_url":"https://api.github.com/repos/jroper/akka/subscribers","subscription_url":"https://api.github.com/repos/jroper/akka/subscription","commits_url":"https://api.github.com/repos/jroper/akka/commits{/sha}","git_commits_url":"https://api.github.com/repos/jroper/akka/git/commits{/sha}","comments_url":"https://api.github.com/repos/jroper/akka/comments{/number}","issue_comment_url":"https://api.github.com/repos/jroper/akka/issues/comments{/number}","contents_url":"https://api.github.com/repos/jroper/akka/contents/{+path}","compare_url":"https://api.github.com/repos/jroper/akka/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jroper/akka/merges","archive_url":"https://api.github.com/repos/jroper/akka/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jroper/akka/downloads","issues_url":"https://api.github.com/repos/jroper/akka/issues{/number}","pulls_url":"https://api.github.com/repos/jroper/akka/pulls{/number}","milestones_url":"https://api.github.com/repos/jroper/akka/milestones{/number}","notifications_url":"https://api.github.com/repos/jroper/akka/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jroper/akka/labels{/name}","releases_url":"https://api.github.com/repos/jroper/akka/releases{/id}","deployments_url":"https://api.github.com/repos/jroper/akka/deployments","created_at":"2015-09-02T07:03:17Z","updated_at":"2015-09-10T17:02:24Z","pushed_at":"2017-07-16T11:21:30Z","git_url":"git://github.com/jroper/akka.git","ssh_url":"git@github.com:jroper/akka.git","clone_url":"https://github.com/jroper/akka.git","svn_url":"https://github.com/jroper/akka","homepage":"http://akka.io","size":199112,"stargazers_count":0,"watchers_count":0,"language":"Scala","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"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":"akka:master","ref":"master","sha":"85ac508d91bfff7136aee9a97029ef7fb2a9189c","user":{"login":"akka","id":1496237,"avatar_url":"https://avatars2.githubusercontent.com/u/1496237?v=4","gravatar_id":"","url":"https://api.github.com/users/akka","html_url":"https://github.com/akka","followers_url":"https://api.github.com/users/akka/followers","following_url":"https://api.github.com/users/akka/following{/other_user}","gists_url":"https://api.github.com/users/akka/gists{/gist_id}","starred_url":"https://api.github.com/users/akka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/akka/subscriptions","organizations_url":"https://api.github.com/users/akka/orgs","repos_url":"https://api.github.com/users/akka/repos","events_url":"https://api.github.com/users/akka/events{/privacy}","received_events_url":"https://api.github.com/users/akka/received_events","type":"Organization","site_admin":false},"repo":{"id":130013,"name":"akka","full_name":"akka/akka","owner":{"login":"akka","id":1496237,"avatar_url":"https://avatars2.githubusercontent.com/u/1496237?v=4","gravatar_id":"","url":"https://api.github.com/users/akka","html_url":"https://github.com/akka","followers_url":"https://api.github.com/users/akka/followers","following_url":"https://api.github.com/users/akka/following{/other_user}","gists_url":"https://api.github.com/users/akka/gists{/gist_id}","starred_url":"https://api.github.com/users/akka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/akka/subscriptions","organizations_url":"https://api.github.com/users/akka/orgs","repos_url":"https://api.github.com/users/akka/repos","events_url":"https://api.github.com/users/akka/events{/privacy}","received_events_url":"https://api.github.com/users/akka/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/akka/akka","description":"Build highly concurrent, distributed, and resilient message-driven applications on the JVM","fork":false,"url":"https://api.github.com/repos/akka/akka","forks_url":"https://api.github.com/repos/akka/akka/forks","keys_url":"https://api.github.com/repos/akka/akka/keys{/key_id}","collaborators_url":"https://api.github.com/repos/akka/akka/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/akka/akka/teams","hooks_url":"https://api.github.com/repos/akka/akka/hooks","issue_events_url":"https://api.github.com/repos/akka/akka/issues/events{/number}","events_url":"https://api.github.com/repos/akka/akka/events","assignees_url":"https://api.github.com/repos/akka/akka/assignees{/user}","branches_url":"https://api.github.com/repos/akka/akka/branches{/branch}","tags_url":"https://api.github.com/repos/akka/akka/tags","blobs_url":"https://api.github.com/repos/akka/akka/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/akka/akka/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/akka/akka/git/refs{/sha}","trees_url":"https://api.github.com/repos/akka/akka/git/trees{/sha}","statuses_url":"https://api.github.com/repos/akka/akka/statuses/{sha}","languages_url":"https://api.github.com/repos/akka/akka/languages","stargazers_url":"https://api.github.com/repos/akka/akka/stargazers","contributors_url":"https://api.github.com/repos/akka/akka/contributors","subscribers_url":"https://api.github.com/repos/akka/akka/subscribers","subscription_url":"https://api.github.com/repos/akka/akka/subscription","commits_url":"https://api.github.com/repos/akka/akka/commits{/sha}","git_commits_url":"https://api.github.com/repos/akka/akka/git/commits{/sha}","comments_url":"https://api.github.com/repos/akka/akka/comments{/number}","issue_comment_url":"https://api.github.com/repos/akka/akka/issues/comments{/number}","contents_url":"https://api.github.com/repos/akka/akka/contents/{+path}","compare_url":"https://api.github.com/repos/akka/akka/compare/{base}...{head}","merges_url":"https://api.github.com/repos/akka/akka/merges","archive_url":"https://api.github.com/repos/akka/akka/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/akka/akka/downloads","issues_url":"https://api.github.com/repos/akka/akka/issues{/number}","pulls_url":"https://api.github.com/repos/akka/akka/pulls{/number}","milestones_url":"https://api.github.com/repos/akka/akka/milestones{/number}","notifications_url":"https://api.github.com/repos/akka/akka/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/akka/akka/labels{/name}","releases_url":"https://api.github.com/repos/akka/akka/releases{/id}","deployments_url":"https://api.github.com/repos/akka/akka/deployments","created_at":"2009-02-16T12:51:54Z","updated_at":"2017-07-19T19:21:17Z","pushed_at":"2017-07-19T21:22:01Z","git_url":"git://github.com/akka/akka.git","ssh_url":"git@github.com:akka/akka.git","clone_url":"https://github.com/akka/akka.git","svn_url":"https://github.com/akka/akka","homepage":"http://akka.io","size":201576,"stargazers_count":7369,"watchers_count":7369,"language":"Scala","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":2342,"mirror_url":null,"open_issues_count":586,"forks":2342,"open_issues":586,"watchers":7369,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/akka/akka/pulls/23367"},"html":{"href":"https://github.com/akka/akka/pull/23367"},"issue":{"href":"https://api.github.com/repos/akka/akka/issues/23367"},"comments":{"href":"https://api.github.com/repos/akka/akka/issues/23367/comments"},"review_comments":{"href":"https://api.github.com/repos/akka/akka/pulls/23367/comments"},"review_comment":{"href":"https://api.github.com/repos/akka/akka/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/akka/akka/pulls/23367/commits"},"statuses":{"href":"https://api.github.com/repos/akka/akka/statuses/5d8a367a6bff39672f1aee9810695c33623adf70"}}}}
{"actor":{"display_login":"ktoso"}}