{"action":"created","comment":{"url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/pulls/comments/87838863","pull_request_review_id":8433785,"id":87838863,"diff_hunk":"@@ -20,45 +20,52 @@ internal static class ActivityTracker\n \r\n         public static ActivityScope Find(string id)\r\n         {\r\n-            if (String.IsNullOrWhiteSpace(id))\r\n+            if (string.IsNullOrWhiteSpace(id))\r\n                 return null;\r\n \r\n-            if (_activityStack.Value != null && _activityStack.Value.Count > 0)\r\n-                return _activityStack.Value.FirstOrDefault(scope => String.Equals(id, scope.Id, StringComparison.InvariantCultureIgnoreCase));\r\n+            if (_activityStack.Value != null && _activityStack.Value.Any())\r\n+                return _activityStack.Value.FirstOrDefault(scope => string.Equals(id, scope.Id, StringComparison.InvariantCultureIgnoreCase));\r\n \r\n             return null;\r\n         }\r\n \r\n-        private static Stack<ActivityScope> ActivityStack {\r\n+        private static ImmutableStack<ActivityScope> ActivityStack {\r\n             get {\r\n                 if (_activityStack.Value == null)\r\n-                    return _activityStack.Value = new Stack<ActivityScope>();\r\n+                    return _activityStack.Value = ImmutableStack<ActivityScope>.Empty;\r\n \r\n                 return _activityStack.Value;\r\n             }\r\n+\r\n+            set\r\n+            {\r\n+                 _activityStack.Value = value;\r\n+            }\r\n         }\r\n \r\n         public static void Start(ActivityScope scope)\r\n         {\r\n-            ActivityScope parent = ActivityStack.Count > 0 ? ActivityStack.Peek() : null;\r\n+            var parent = ActivityStack.Any() ? ActivityStack.Peek() : null;\r\n \r\n             if (parent != null)\r\n                 scope.ParentId = parent.Id;\r\n \r\n-            ActivityStack.Push(scope);\r\n+            ActivityStack = ActivityStack.Push(scope);\r\n         }\r\n \r\n         public static void End(ActivityScope scope)\r\n         {\r\n             if (Current == null)\r\n                 return;\r\n \r\n-            if (!ActivityStack.Any(scopeOnTheStack => scope.Id == scopeOnTheStack.Id))\r\n+            if (ActivityStack.All(scopeOnTheStack => scope.Id != scopeOnTheStack.Id))\r\n                 return;\r\n \r\n-            ActivityScope currentScope = ActivityStack.Pop();\r\n-            while(ActivityStack.Count > 0 && currentScope.Id != scope.Id) {\r\n-                currentScope = ActivityStack.Pop();\r\n+            ActivityScope currentScope;\r\n+            ActivityStack = ActivityStack.Pop(out currentScope);\r\n+\r\n+            while(ActivityStack.Any() && currentScope.Id != scope.Id) {\r","path":"CorrelatorSharp/ActivityTracker.cs","position":80,"original_position":80,"commit_id":"d3bc69ca8d4a8cbf8e61b9e816a6dc555910e5ed","original_commit_id":"d3bc69ca8d4a8cbf8e61b9e816a6dc555910e5ed","user":{"login":"mikegoatly","id":4577868,"avatar_url":"https://avatars.githubusercontent.com/u/4577868?v=3","gravatar_id":"","url":"https://api.github.com/users/mikegoatly","html_url":"https://github.com/mikegoatly","followers_url":"https://api.github.com/users/mikegoatly/followers","following_url":"https://api.github.com/users/mikegoatly/following{/other_user}","gists_url":"https://api.github.com/users/mikegoatly/gists{/gist_id}","starred_url":"https://api.github.com/users/mikegoatly/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mikegoatly/subscriptions","organizations_url":"https://api.github.com/users/mikegoatly/orgs","repos_url":"https://api.github.com/users/mikegoatly/repos","events_url":"https://api.github.com/users/mikegoatly/events{/privacy}","received_events_url":"https://api.github.com/users/mikegoatly/received_events","type":"User","site_admin":false},"body":"Not sure why this loop would be needed - surely there should only ever be 1 push for 1 pop; popping multiple times on End feels like plastering over something that was incorrect before?","created_at":"2016-11-14T16:37:47Z","updated_at":"2016-11-14T16:37:47Z","html_url":"https://github.com/CorrelatorSharp/CorrelatorSharp/pull/20#discussion_r87838863","pull_request_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/pulls/20","_links":{"self":{"href":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/pulls/comments/87838863"},"html":{"href":"https://github.com/CorrelatorSharp/CorrelatorSharp/pull/20#discussion_r87838863"},"pull_request":{"href":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/pulls/20"}}},"pull_request":{"url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/pulls/20","id":93593242,"html_url":"https://github.com/CorrelatorSharp/CorrelatorSharp/pull/20","diff_url":"https://github.com/CorrelatorSharp/CorrelatorSharp/pull/20.diff","patch_url":"https://github.com/CorrelatorSharp/CorrelatorSharp/pull/20.patch","issue_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/issues/20","number":20,"state":"open","locked":false,"title":"Fix issues with AsyncLocal activity scope stack implementation","user":{"login":"masoapps","id":12562266,"avatar_url":"https://avatars.githubusercontent.com/u/12562266?v=3","gravatar_id":"","url":"https://api.github.com/users/masoapps","html_url":"https://github.com/masoapps","followers_url":"https://api.github.com/users/masoapps/followers","following_url":"https://api.github.com/users/masoapps/following{/other_user}","gists_url":"https://api.github.com/users/masoapps/gists{/gist_id}","starred_url":"https://api.github.com/users/masoapps/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/masoapps/subscriptions","organizations_url":"https://api.github.com/users/masoapps/orgs","repos_url":"https://api.github.com/users/masoapps/repos","events_url":"https://api.github.com/users/masoapps/events{/privacy}","received_events_url":"https://api.github.com/users/masoapps/received_events","type":"User","site_admin":false},"body":"Using ```AsyncLocal<Stack<ActivityScope>>```  creates race conditions and allows unexpected changes to occur to the activity scope stack when there are multiple async children running.  Implementing ```AsyncLocal<ImmutableStack<ActivityScope>>``` enforces copying and prevents these issues.\r\n\r\nOne particular issue it addresses is an exception we had been seeing of the form:\r\n```\r\nStack empty. System.InvalidOperationException: Stack empty.\\r\\n   at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)\\r\\n   at System.Collections.Generic.Stack`1.Pop()\\r\\n   at CorrelatorSharp.ActivityTracker.End(ActivityScope scope)\\r\\n   at CorrelatorSharp.ActivityScope.Dispose()\\r\\n\r\n```\r\n\r\nIt also addresses the issue where if you spawn two portions of async work, the second portion of async work would be inherit the first async as it's parent even if actually independent.\r\n\r\nAdded relevant test for this.","created_at":"2016-11-14T15:59:41Z","updated_at":"2016-11-14T16:37:47Z","closed_at":null,"merged_at":null,"merge_commit_sha":"b68cf560cfd0983559f6276050f6ed062e2663db","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/pulls/20/commits","review_comments_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/pulls/20/comments","review_comment_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/pulls/comments{/number}","comments_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/issues/20/comments","statuses_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/statuses/d3bc69ca8d4a8cbf8e61b9e816a6dc555910e5ed","head":{"label":"masoapps:fix-async-local-stack","ref":"fix-async-local-stack","sha":"d3bc69ca8d4a8cbf8e61b9e816a6dc555910e5ed","user":{"login":"masoapps","id":12562266,"avatar_url":"https://avatars.githubusercontent.com/u/12562266?v=3","gravatar_id":"","url":"https://api.github.com/users/masoapps","html_url":"https://github.com/masoapps","followers_url":"https://api.github.com/users/masoapps/followers","following_url":"https://api.github.com/users/masoapps/following{/other_user}","gists_url":"https://api.github.com/users/masoapps/gists{/gist_id}","starred_url":"https://api.github.com/users/masoapps/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/masoapps/subscriptions","organizations_url":"https://api.github.com/users/masoapps/orgs","repos_url":"https://api.github.com/users/masoapps/repos","events_url":"https://api.github.com/users/masoapps/events{/privacy}","received_events_url":"https://api.github.com/users/masoapps/received_events","type":"User","site_admin":false},"repo":{"id":73692706,"name":"CorrelatorSharp","full_name":"masoapps/CorrelatorSharp","owner":{"login":"masoapps","id":12562266,"avatar_url":"https://avatars.githubusercontent.com/u/12562266?v=3","gravatar_id":"","url":"https://api.github.com/users/masoapps","html_url":"https://github.com/masoapps","followers_url":"https://api.github.com/users/masoapps/followers","following_url":"https://api.github.com/users/masoapps/following{/other_user}","gists_url":"https://api.github.com/users/masoapps/gists{/gist_id}","starred_url":"https://api.github.com/users/masoapps/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/masoapps/subscriptions","organizations_url":"https://api.github.com/users/masoapps/orgs","repos_url":"https://api.github.com/users/masoapps/repos","events_url":"https://api.github.com/users/masoapps/events{/privacy}","received_events_url":"https://api.github.com/users/masoapps/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/masoapps/CorrelatorSharp","description":"Your one stop shop for context-aware logging and diagnostics","fork":true,"url":"https://api.github.com/repos/masoapps/CorrelatorSharp","forks_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/forks","keys_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/keys{/key_id}","collaborators_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/teams","hooks_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/hooks","issue_events_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/issues/events{/number}","events_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/events","assignees_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/assignees{/user}","branches_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/branches{/branch}","tags_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/tags","blobs_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/git/refs{/sha}","trees_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/git/trees{/sha}","statuses_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/statuses/{sha}","languages_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/languages","stargazers_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/stargazers","contributors_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/contributors","subscribers_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/subscribers","subscription_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/subscription","commits_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/commits{/sha}","git_commits_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/git/commits{/sha}","comments_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/comments{/number}","issue_comment_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/issues/comments{/number}","contents_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/contents/{+path}","compare_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/compare/{base}...{head}","merges_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/merges","archive_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/downloads","issues_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/issues{/number}","pulls_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/pulls{/number}","milestones_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/milestones{/number}","notifications_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/labels{/name}","releases_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/releases{/id}","deployments_url":"https://api.github.com/repos/masoapps/CorrelatorSharp/deployments","created_at":"2016-11-14T10:17:24Z","updated_at":"2016-11-14T10:17:26Z","pushed_at":"2016-11-14T15:53:40Z","git_url":"git://github.com/masoapps/CorrelatorSharp.git","ssh_url":"git@github.com:masoapps/CorrelatorSharp.git","clone_url":"https://github.com/masoapps/CorrelatorSharp.git","svn_url":"https://github.com/masoapps/CorrelatorSharp","homepage":"","size":543,"stargazers_count":0,"watchers_count":0,"language":"C#","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":"CorrelatorSharp:master","ref":"master","sha":"3005be38ef29f3112fb0f1b8569eea955c944e8a","user":{"login":"CorrelatorSharp","id":17390119,"avatar_url":"https://avatars.githubusercontent.com/u/17390119?v=3","gravatar_id":"","url":"https://api.github.com/users/CorrelatorSharp","html_url":"https://github.com/CorrelatorSharp","followers_url":"https://api.github.com/users/CorrelatorSharp/followers","following_url":"https://api.github.com/users/CorrelatorSharp/following{/other_user}","gists_url":"https://api.github.com/users/CorrelatorSharp/gists{/gist_id}","starred_url":"https://api.github.com/users/CorrelatorSharp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CorrelatorSharp/subscriptions","organizations_url":"https://api.github.com/users/CorrelatorSharp/orgs","repos_url":"https://api.github.com/users/CorrelatorSharp/repos","events_url":"https://api.github.com/users/CorrelatorSharp/events{/privacy}","received_events_url":"https://api.github.com/users/CorrelatorSharp/received_events","type":"Organization","site_admin":false},"repo":{"id":44453798,"name":"CorrelatorSharp","full_name":"CorrelatorSharp/CorrelatorSharp","owner":{"login":"CorrelatorSharp","id":17390119,"avatar_url":"https://avatars.githubusercontent.com/u/17390119?v=3","gravatar_id":"","url":"https://api.github.com/users/CorrelatorSharp","html_url":"https://github.com/CorrelatorSharp","followers_url":"https://api.github.com/users/CorrelatorSharp/followers","following_url":"https://api.github.com/users/CorrelatorSharp/following{/other_user}","gists_url":"https://api.github.com/users/CorrelatorSharp/gists{/gist_id}","starred_url":"https://api.github.com/users/CorrelatorSharp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CorrelatorSharp/subscriptions","organizations_url":"https://api.github.com/users/CorrelatorSharp/orgs","repos_url":"https://api.github.com/users/CorrelatorSharp/repos","events_url":"https://api.github.com/users/CorrelatorSharp/events{/privacy}","received_events_url":"https://api.github.com/users/CorrelatorSharp/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/CorrelatorSharp/CorrelatorSharp","description":"Your one stop shop for context-aware logging and diagnostics","fork":false,"url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp","forks_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/forks","keys_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/keys{/key_id}","collaborators_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/teams","hooks_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/hooks","issue_events_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/issues/events{/number}","events_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/events","assignees_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/assignees{/user}","branches_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/branches{/branch}","tags_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/tags","blobs_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/git/refs{/sha}","trees_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/git/trees{/sha}","statuses_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/statuses/{sha}","languages_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/languages","stargazers_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/stargazers","contributors_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/contributors","subscribers_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/subscribers","subscription_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/subscription","commits_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/commits{/sha}","git_commits_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/git/commits{/sha}","comments_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/comments{/number}","issue_comment_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/issues/comments{/number}","contents_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/contents/{+path}","compare_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/compare/{base}...{head}","merges_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/merges","archive_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/downloads","issues_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/issues{/number}","pulls_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/pulls{/number}","milestones_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/milestones{/number}","notifications_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/labels{/name}","releases_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/releases{/id}","deployments_url":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/deployments","created_at":"2015-10-17T20:43:07Z","updated_at":"2016-09-24T15:47:35Z","pushed_at":"2016-11-14T15:59:41Z","git_url":"git://github.com/CorrelatorSharp/CorrelatorSharp.git","ssh_url":"git@github.com:CorrelatorSharp/CorrelatorSharp.git","clone_url":"https://github.com/CorrelatorSharp/CorrelatorSharp.git","svn_url":"https://github.com/CorrelatorSharp/CorrelatorSharp","homepage":"","size":546,"stargazers_count":9,"watchers_count":9,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"open_issues_count":7,"forks":4,"open_issues":7,"watchers":9,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/pulls/20"},"html":{"href":"https://github.com/CorrelatorSharp/CorrelatorSharp/pull/20"},"issue":{"href":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/issues/20"},"comments":{"href":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/issues/20/comments"},"review_comments":{"href":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/pulls/20/comments"},"review_comment":{"href":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/pulls/20/commits"},"statuses":{"href":"https://api.github.com/repos/CorrelatorSharp/CorrelatorSharp/statuses/d3bc69ca8d4a8cbf8e61b9e816a6dc555910e5ed"}}}}
{"actor":{"display_login":"mikegoatly"}}