{"action":"created","issue":{"url":"https://api.github.com/repos/Kotlin/kotlinx.coroutines/issues/220","repository_url":"https://api.github.com/repos/Kotlin/kotlinx.coroutines","labels_url":"https://api.github.com/repos/Kotlin/kotlinx.coroutines/issues/220/labels{/name}","comments_url":"https://api.github.com/repos/Kotlin/kotlinx.coroutines/issues/220/comments","events_url":"https://api.github.com/repos/Kotlin/kotlinx.coroutines/issues/220/events","html_url":"https://github.com/Kotlin/kotlinx.coroutines/issues/220","id":294487646,"node_id":"MDU6SXNzdWUyOTQ0ODc2NDY=","number":220,"title":"Abolish distinction between cancelled and failed Job/Deferred","user":{"login":"elizarov","id":478679,"node_id":"MDQ6VXNlcjQ3ODY3OQ==","avatar_url":"https://avatars2.githubusercontent.com/u/478679?v=4","gravatar_id":"","url":"https://api.github.com/users/elizarov","html_url":"https://github.com/elizarov","followers_url":"https://api.github.com/users/elizarov/followers","following_url":"https://api.github.com/users/elizarov/following{/other_user}","gists_url":"https://api.github.com/users/elizarov/gists{/gist_id}","starred_url":"https://api.github.com/users/elizarov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elizarov/subscriptions","organizations_url":"https://api.github.com/users/elizarov/orgs","repos_url":"https://api.github.com/users/elizarov/repos","events_url":"https://api.github.com/users/elizarov/events{/privacy}","received_events_url":"https://api.github.com/users/elizarov/received_events","type":"User","site_admin":false},"labels":[{"id":396785979,"node_id":"MDU6TGFiZWwzOTY3ODU5Nzk=","url":"https://api.github.com/repos/Kotlin/kotlinx.coroutines/labels/enhancement","name":"enhancement","color":"84b6eb","default":true},{"id":846438600,"node_id":"MDU6TGFiZWw4NDY0Mzg2MDA=","url":"https://api.github.com/repos/Kotlin/kotlinx.coroutines/labels/for%201.0%20release","name":"for 1.0 release","color":"d510ef","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":8,"created_at":"2018-02-05T18:02:42Z","updated_at":"2018-09-25T11:27:32Z","closed_at":null,"author_association":"COLLABORATOR","body":"Distinction between _cancelled_ and _failed_ states for `Job` and `Deferred` shall be abolished. The rationale follows.\r\n\r\n1. Public documentation for `Job` does not mention the _failed_ state at all, however using `getCancellationException` one can still indirectly figure out if the coroutine that was started with `launch` had completed normally or with exception, so hiding that from the `Job` state machine does not really help.\r\n\r\n2. When `Job` uses parallel decomposition of its work by launching child coroutines it accidentally leaks its internal implementation details. When a child coroutine crashes with exception it cancels its parent, thereby obviously revealing this failure with _cancelled_ state of the parent job. However, when the parent itself crashes, it still technically in _completed_ state (not _cancelled_), but see above.\r\n\r\n3. When the parent coroutine completes exceptionally it waits for its children before becoming _failed_. This is not an ideal behavior for a parallel decomposition of work. When the parent coroutine crashes, then we really want to cancel all the children asap, since the \"work as a whole\" was obviously not successful.\r\n\r\nAll in all, this makes distinction between _cancelled_ and _failed_ `Job` or `Deferred` really irrelevant. \r\n\r\nThe plan is as follows:\r\n\r\n* Deprecate `Deferred.isCompletedExceptionally` in favor of `isCancelled`.\r\n* Deprecate `CompletableDeferred.completeExceptionally` in favor of `cancel`.\r\n\r\nChange the behavior for crashed coroutines. When coroutine crashes with exception it shall transition into _cancelling_ state, cancel all its children, wait for their completion, and transition into _cancelled_ state.\r\n\r\nWith this change the behavior of `CoroutineExceptionHandler` is going to be more consistent. When a standalone coroutine (the coroutine that is started with `launch`) crashes with exception or is cancelled it should transition to _cancelling_ state and invoke `CoroutineExceptionHandler` with the context of the parent coroutine. The default behavior is to cancel the parent. Since the crashed child is already in the _cancelling_ state it is never going cause a problem of cancelling the _failing_ child. \r\n\r\nDocumentation needs to be adjusted appropriately. In particular, the state machine for `Deferred` is going to be identical to a `Job` and its docs can be simpler and more focused on the `Deferred`/`Job` differences.\r\n\r\n#219 shall be implemented first, since `CancellableContinuation` must keep distinction between the state where it was \"resumed with exception\" and where it was \"cancelled\". This is often needed to for a proper resource-managent to avoid closing some external resource when it was already closed and the continuation was cancelled.\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/Kotlin/kotlinx.coroutines/issues/comments/424306132","html_url":"https://github.com/Kotlin/kotlinx.coroutines/issues/220#issuecomment-424306132","issue_url":"https://api.github.com/repos/Kotlin/kotlinx.coroutines/issues/220","id":424306132,"node_id":"MDEyOklzc3VlQ29tbWVudDQyNDMwNjEzMg==","user":{"login":"elizarov","id":478679,"node_id":"MDQ6VXNlcjQ3ODY3OQ==","avatar_url":"https://avatars2.githubusercontent.com/u/478679?v=4","gravatar_id":"","url":"https://api.github.com/users/elizarov","html_url":"https://github.com/elizarov","followers_url":"https://api.github.com/users/elizarov/followers","following_url":"https://api.github.com/users/elizarov/following{/other_user}","gists_url":"https://api.github.com/users/elizarov/gists{/gist_id}","starred_url":"https://api.github.com/users/elizarov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elizarov/subscriptions","organizations_url":"https://api.github.com/users/elizarov/orgs","repos_url":"https://api.github.com/users/elizarov/repos","events_url":"https://api.github.com/users/elizarov/events{/privacy}","received_events_url":"https://api.github.com/users/elizarov/received_events","type":"User","site_admin":false},"created_at":"2018-09-25T11:27:32Z","updated_at":"2018-09-25T11:27:32Z","author_association":"COLLABORATOR","body":"We're back on track. We've figured out how to preserve all our channel-related use-cases while abolishing cancelling/failing distinction. Job becomes conceptually so much simpler."}}
{"actor":{"display_login":"elizarov"}}