{"action":"created","comment":{"url":"https://api.github.com/repos/nodejs/node/pulls/comments/59357757","id":59357757,"diff_hunk":"@@ -0,0 +1,138 @@\n+# Domain Module Postmortem\n+\n+## Usability Issues\n+\n+### Implicit Behavior\n+\n+It's possible for a developer to create a new domain and then simply run\n+`domain.enter()`. Which then acts as a catch-all for any exception in the\n+future that couldn't be observed by the thrower. Allowing a module author to\n+intercept the exceptions of unrelated code in a different module. Preventing\n+the originator of the code from knowing about its own exceptions.\n+\n+Another issue is that domains route errors automatically if no `'error'`\n+handler was set on the event emitter. There is no opt-in mechanism for this,\n+and automatically propagates across the entire asynchronous chain. This may\n+seem useful at first, but once asynchronous calls are two or more modules deep\n+and one of them doesn't include an error handler the creator of the domain will\n+suddenly be catching unexpected exceptions, and the thrower's exception will go\n+unnoticed by the author.\n+\n+\n+### API Gaps\n+\n+While APIs based using `EventEmitter` can use `bind()` and errback style\n+callbacks can use `intercept()`, alternative APIs that implicitly bind to the\n+active domain must be executed inside of `run()`. Meaning if module authors\n+wanted to support domains using a mechanism alternative to those mentioned they\n+must manually implement domain support themselves. Instead of being able to\n+leverage the implicit mechanisms already in place.\n+\n+\n+### Error Propagation\n+\n+Propagating errors across nested domains is not straight forward, if even\n+possible. Existing documentation shows a simple example of how to `close()` an\n+`http` server if there is an error in the request handler. What it does not\n+explain is how to close the server if the request handler creates another\n+domain instance for another async request. Using the following as a simple\n+example of the failing of error propagation:\n+\n+```js\n+const d1 = domain.create();\n+d1.foo = true;  // custom member to make more visible in console\n+d1.on('error', (er) => { /* handle error */ });\n+\n+d1.run(() => setTimeout(() => {\n+  const d2 = domain.create();\n+  d2.bar = 43;\n+  d2.on('error', (er) => console.error(er.message, domain._stack));\n+  d2.run(() => {\n+    setTimeout(() => {\n+      setTimeout(() => {\n+        throw new Error('AGAIN?');\n+      });\n+      throw new Error('ah crap')\n+    });\n+  });\n+}));\n+```\n+\n+Even in the case that the domain instances are being used for local storage so\n+access to resources are made available there is still no way to allow the error\n+to continue propagating from `d2` back to `d1`. Quick inspection may tell us\n+that simply throwing from `d2`'s domain `'error'` handler would allow `d1` to\n+then catch the exception and execute its own error handler. Though that is not\n+the case. Upon inspection of `domain._stack` you'll see that the stack only\n+contains `d2`.\n+\n+This may be considered a failing of the API, but even if it did operate in this\n+way there is still the issue of transmitting the fact that a branch in the\n+asynchronous execution has failed, and that all further operations in that\n+branch must cease. In the example of the http request handler, if we fire off\n+several asynchronous requests and each one then `write()`'s data back to the\n+client many more errors will arise from attempting to `write()` to a closed\n+handle. More on this in _Resource Cleanup on Exception_.\n+\n+\n+### Resource Cleanup on Exception\n+\n+The script [`domain-resource-cleanup.js`](domain-resource-cleanup.js)\n+contains a more complex example of properly cleaning up in a small resource\n+dependency tree in the case that an exception occurs in a given connection or\n+any of its dependencies. Breaking down the script into its basic operations:\n+\n+- On new connection:\n+  - Open a file on the file system\n+  - Open Pipe to unique socket\n+- Read a chunk of the file asynchronously\n+- Write chunk to both the TCP connection and any listening sockets\n+- If any of these resources error, notify all other attached resources that\n+  they need to clean up and shutdown\n+\n+As we can see from this example a lot more must be done to properly clean up\n+resources when something fails than what can be done strictly through the\n+domain API. All that domains offer is an exception aggregation mechanism. Even\n+the potentially useful ability to propagate data with the domain is easily\n+countered, in this example, by passing the needed resources as a function\n+argument.","path":"doc/topics/domain-postmortem.md","position":98,"original_position":98,"commit_id":"e51b4b1e314cc6276142764d32281ece56eb1130","original_commit_id":"e51b4b1e314cc6276142764d32281ece56eb1130","user":{"login":"benjamingr","id":1315533,"avatar_url":"https://avatars.githubusercontent.com/u/1315533?v=3","gravatar_id":"","url":"https://api.github.com/users/benjamingr","html_url":"https://github.com/benjamingr","followers_url":"https://api.github.com/users/benjamingr/followers","following_url":"https://api.github.com/users/benjamingr/following{/other_user}","gists_url":"https://api.github.com/users/benjamingr/gists{/gist_id}","starred_url":"https://api.github.com/users/benjamingr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/benjamingr/subscriptions","organizations_url":"https://api.github.com/users/benjamingr/orgs","repos_url":"https://api.github.com/users/benjamingr/repos","events_url":"https://api.github.com/users/benjamingr/events{/privacy}","received_events_url":"https://api.github.com/users/benjamingr/received_events","type":"User","site_admin":false},"body":"For what it's worth, most complaints I've seen about deprecating domains are about context and not error handling. ","created_at":"2016-04-12T11:06:58Z","updated_at":"2016-04-12T11:06:58Z","html_url":"https://github.com/nodejs/node/pull/6159#discussion_r59357757","pull_request_url":"https://api.github.com/repos/nodejs/node/pulls/6159","_links":{"self":{"href":"https://api.github.com/repos/nodejs/node/pulls/comments/59357757"},"html":{"href":"https://github.com/nodejs/node/pull/6159#discussion_r59357757"},"pull_request":{"href":"https://api.github.com/repos/nodejs/node/pulls/6159"}}},"pull_request":{"url":"https://api.github.com/repos/nodejs/node/pulls/6159","id":66073703,"html_url":"https://github.com/nodejs/node/pull/6159","diff_url":"https://github.com/nodejs/node/pull/6159.diff","patch_url":"https://github.com/nodejs/node/pull/6159.patch","issue_url":"https://api.github.com/repos/nodejs/node/issues/6159","number":6159,"state":"open","locked":false,"title":"doc: add domain post mortem","user":{"login":"trevnorris","id":289174,"avatar_url":"https://avatars.githubusercontent.com/u/289174?v=3","gravatar_id":"","url":"https://api.github.com/users/trevnorris","html_url":"https://github.com/trevnorris","followers_url":"https://api.github.com/users/trevnorris/followers","following_url":"https://api.github.com/users/trevnorris/following{/other_user}","gists_url":"https://api.github.com/users/trevnorris/gists{/gist_id}","starred_url":"https://api.github.com/users/trevnorris/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/trevnorris/subscriptions","organizations_url":"https://api.github.com/users/trevnorris/orgs","repos_url":"https://api.github.com/users/trevnorris/repos","events_url":"https://api.github.com/users/trevnorris/events{/privacy}","received_events_url":"https://api.github.com/users/trevnorris/received_events","type":"User","site_admin":false},"body":"##### Checklist\r\n\r\n- [x] documentation is changed or added\r\n- [x] the commit message follows commit guidelines\r\n\r\n##### Affected core subsystem(s)\r\n\r\ndoc\r\n\r\n##### Description of change\r\n\r\nThe domain module did not live a long and fruitful life. Instead it was\r\nultimately deprecated and abandon. The domain postmortem addresses why\r\nthis happened so that it doesn't happen again in the future.\r\n\r\nAlso included is an example script that accompanies the postmortem\r\nanalysis.\r\n\r\nR=@Fishrock123 \r\nR=@nodejs/documentation ","created_at":"2016-04-11T22:34:36Z","updated_at":"2016-04-12T11:06:58Z","closed_at":null,"merged_at":null,"merge_commit_sha":"e4076b8508701c49417a32d275e9754580ac154f","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/nodejs/node/pulls/6159/commits","review_comments_url":"https://api.github.com/repos/nodejs/node/pulls/6159/comments","review_comment_url":"https://api.github.com/repos/nodejs/node/pulls/comments{/number}","comments_url":"https://api.github.com/repos/nodejs/node/issues/6159/comments","statuses_url":"https://api.github.com/repos/nodejs/node/statuses/e51b4b1e314cc6276142764d32281ece56eb1130","head":{"label":"trevnorris:domain-postmortem","ref":"domain-postmortem","sha":"e51b4b1e314cc6276142764d32281ece56eb1130","user":{"login":"trevnorris","id":289174,"avatar_url":"https://avatars.githubusercontent.com/u/289174?v=3","gravatar_id":"","url":"https://api.github.com/users/trevnorris","html_url":"https://github.com/trevnorris","followers_url":"https://api.github.com/users/trevnorris/followers","following_url":"https://api.github.com/users/trevnorris/following{/other_user}","gists_url":"https://api.github.com/users/trevnorris/gists{/gist_id}","starred_url":"https://api.github.com/users/trevnorris/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/trevnorris/subscriptions","organizations_url":"https://api.github.com/users/trevnorris/orgs","repos_url":"https://api.github.com/users/trevnorris/repos","events_url":"https://api.github.com/users/trevnorris/events{/privacy}","received_events_url":"https://api.github.com/users/trevnorris/received_events","type":"User","site_admin":false},"repo":{"id":29560577,"name":"node","full_name":"trevnorris/node","owner":{"login":"trevnorris","id":289174,"avatar_url":"https://avatars.githubusercontent.com/u/289174?v=3","gravatar_id":"","url":"https://api.github.com/users/trevnorris","html_url":"https://github.com/trevnorris","followers_url":"https://api.github.com/users/trevnorris/followers","following_url":"https://api.github.com/users/trevnorris/following{/other_user}","gists_url":"https://api.github.com/users/trevnorris/gists{/gist_id}","starred_url":"https://api.github.com/users/trevnorris/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/trevnorris/subscriptions","organizations_url":"https://api.github.com/users/trevnorris/orgs","repos_url":"https://api.github.com/users/trevnorris/repos","events_url":"https://api.github.com/users/trevnorris/events{/privacy}","received_events_url":"https://api.github.com/users/trevnorris/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/trevnorris/node","description":"Personal fork of node","fork":true,"url":"https://api.github.com/repos/trevnorris/node","forks_url":"https://api.github.com/repos/trevnorris/node/forks","keys_url":"https://api.github.com/repos/trevnorris/node/keys{/key_id}","collaborators_url":"https://api.github.com/repos/trevnorris/node/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/trevnorris/node/teams","hooks_url":"https://api.github.com/repos/trevnorris/node/hooks","issue_events_url":"https://api.github.com/repos/trevnorris/node/issues/events{/number}","events_url":"https://api.github.com/repos/trevnorris/node/events","assignees_url":"https://api.github.com/repos/trevnorris/node/assignees{/user}","branches_url":"https://api.github.com/repos/trevnorris/node/branches{/branch}","tags_url":"https://api.github.com/repos/trevnorris/node/tags","blobs_url":"https://api.github.com/repos/trevnorris/node/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/trevnorris/node/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/trevnorris/node/git/refs{/sha}","trees_url":"https://api.github.com/repos/trevnorris/node/git/trees{/sha}","statuses_url":"https://api.github.com/repos/trevnorris/node/statuses/{sha}","languages_url":"https://api.github.com/repos/trevnorris/node/languages","stargazers_url":"https://api.github.com/repos/trevnorris/node/stargazers","contributors_url":"https://api.github.com/repos/trevnorris/node/contributors","subscribers_url":"https://api.github.com/repos/trevnorris/node/subscribers","subscription_url":"https://api.github.com/repos/trevnorris/node/subscription","commits_url":"https://api.github.com/repos/trevnorris/node/commits{/sha}","git_commits_url":"https://api.github.com/repos/trevnorris/node/git/commits{/sha}","comments_url":"https://api.github.com/repos/trevnorris/node/comments{/number}","issue_comment_url":"https://api.github.com/repos/trevnorris/node/issues/comments{/number}","contents_url":"https://api.github.com/repos/trevnorris/node/contents/{+path}","compare_url":"https://api.github.com/repos/trevnorris/node/compare/{base}...{head}","merges_url":"https://api.github.com/repos/trevnorris/node/merges","archive_url":"https://api.github.com/repos/trevnorris/node/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/trevnorris/node/downloads","issues_url":"https://api.github.com/repos/trevnorris/node/issues{/number}","pulls_url":"https://api.github.com/repos/trevnorris/node/pulls{/number}","milestones_url":"https://api.github.com/repos/trevnorris/node/milestones{/number}","notifications_url":"https://api.github.com/repos/trevnorris/node/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/trevnorris/node/labels{/name}","releases_url":"https://api.github.com/repos/trevnorris/node/releases{/id}","deployments_url":"https://api.github.com/repos/trevnorris/node/deployments","created_at":"2015-01-20T23:22:42Z","updated_at":"2016-03-17T07:55:00Z","pushed_at":"2016-04-12T06:17:32Z","git_url":"git://github.com/trevnorris/node.git","ssh_url":"git@github.com:trevnorris/node.git","clone_url":"https://github.com/trevnorris/node.git","svn_url":"https://github.com/trevnorris/node","homepage":"https://nodejs.org","size":180921,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","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":"nodejs:master","ref":"master","sha":"819b2d36bcffdb9f33e0e4497ac818d64fe5711d","user":{"login":"nodejs","id":9950313,"avatar_url":"https://avatars.githubusercontent.com/u/9950313?v=3","gravatar_id":"","url":"https://api.github.com/users/nodejs","html_url":"https://github.com/nodejs","followers_url":"https://api.github.com/users/nodejs/followers","following_url":"https://api.github.com/users/nodejs/following{/other_user}","gists_url":"https://api.github.com/users/nodejs/gists{/gist_id}","starred_url":"https://api.github.com/users/nodejs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nodejs/subscriptions","organizations_url":"https://api.github.com/users/nodejs/orgs","repos_url":"https://api.github.com/users/nodejs/repos","events_url":"https://api.github.com/users/nodejs/events{/privacy}","received_events_url":"https://api.github.com/users/nodejs/received_events","type":"Organization","site_admin":false},"repo":{"id":27193779,"name":"node","full_name":"nodejs/node","owner":{"login":"nodejs","id":9950313,"avatar_url":"https://avatars.githubusercontent.com/u/9950313?v=3","gravatar_id":"","url":"https://api.github.com/users/nodejs","html_url":"https://github.com/nodejs","followers_url":"https://api.github.com/users/nodejs/followers","following_url":"https://api.github.com/users/nodejs/following{/other_user}","gists_url":"https://api.github.com/users/nodejs/gists{/gist_id}","starred_url":"https://api.github.com/users/nodejs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nodejs/subscriptions","organizations_url":"https://api.github.com/users/nodejs/orgs","repos_url":"https://api.github.com/users/nodejs/repos","events_url":"https://api.github.com/users/nodejs/events{/privacy}","received_events_url":"https://api.github.com/users/nodejs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/nodejs/node","description":"Node.js JavaScript runtime :sparkles::turtle::rocket::sparkles:","fork":false,"url":"https://api.github.com/repos/nodejs/node","forks_url":"https://api.github.com/repos/nodejs/node/forks","keys_url":"https://api.github.com/repos/nodejs/node/keys{/key_id}","collaborators_url":"https://api.github.com/repos/nodejs/node/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/nodejs/node/teams","hooks_url":"https://api.github.com/repos/nodejs/node/hooks","issue_events_url":"https://api.github.com/repos/nodejs/node/issues/events{/number}","events_url":"https://api.github.com/repos/nodejs/node/events","assignees_url":"https://api.github.com/repos/nodejs/node/assignees{/user}","branches_url":"https://api.github.com/repos/nodejs/node/branches{/branch}","tags_url":"https://api.github.com/repos/nodejs/node/tags","blobs_url":"https://api.github.com/repos/nodejs/node/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/nodejs/node/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/nodejs/node/git/refs{/sha}","trees_url":"https://api.github.com/repos/nodejs/node/git/trees{/sha}","statuses_url":"https://api.github.com/repos/nodejs/node/statuses/{sha}","languages_url":"https://api.github.com/repos/nodejs/node/languages","stargazers_url":"https://api.github.com/repos/nodejs/node/stargazers","contributors_url":"https://api.github.com/repos/nodejs/node/contributors","subscribers_url":"https://api.github.com/repos/nodejs/node/subscribers","subscription_url":"https://api.github.com/repos/nodejs/node/subscription","commits_url":"https://api.github.com/repos/nodejs/node/commits{/sha}","git_commits_url":"https://api.github.com/repos/nodejs/node/git/commits{/sha}","comments_url":"https://api.github.com/repos/nodejs/node/comments{/number}","issue_comment_url":"https://api.github.com/repos/nodejs/node/issues/comments{/number}","contents_url":"https://api.github.com/repos/nodejs/node/contents/{+path}","compare_url":"https://api.github.com/repos/nodejs/node/compare/{base}...{head}","merges_url":"https://api.github.com/repos/nodejs/node/merges","archive_url":"https://api.github.com/repos/nodejs/node/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/nodejs/node/downloads","issues_url":"https://api.github.com/repos/nodejs/node/issues{/number}","pulls_url":"https://api.github.com/repos/nodejs/node/pulls{/number}","milestones_url":"https://api.github.com/repos/nodejs/node/milestones{/number}","notifications_url":"https://api.github.com/repos/nodejs/node/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/nodejs/node/labels{/name}","releases_url":"https://api.github.com/repos/nodejs/node/releases{/id}","deployments_url":"https://api.github.com/repos/nodejs/node/deployments","created_at":"2014-11-26T19:57:11Z","updated_at":"2016-04-12T11:02:37Z","pushed_at":"2016-04-12T10:51:02Z","git_url":"git://github.com/nodejs/node.git","ssh_url":"git@github.com:nodejs/node.git","clone_url":"https://github.com/nodejs/node.git","svn_url":"https://github.com/nodejs/node","homepage":"https://nodejs.org","size":232914,"stargazers_count":21961,"watchers_count":21961,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2950,"mirror_url":null,"open_issues_count":684,"forks":2950,"open_issues":684,"watchers":21961,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/nodejs/node/pulls/6159"},"html":{"href":"https://github.com/nodejs/node/pull/6159"},"issue":{"href":"https://api.github.com/repos/nodejs/node/issues/6159"},"comments":{"href":"https://api.github.com/repos/nodejs/node/issues/6159/comments"},"review_comments":{"href":"https://api.github.com/repos/nodejs/node/pulls/6159/comments"},"review_comment":{"href":"https://api.github.com/repos/nodejs/node/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/nodejs/node/pulls/6159/commits"},"statuses":{"href":"https://api.github.com/repos/nodejs/node/statuses/e51b4b1e314cc6276142764d32281ece56eb1130"}}}}