{"action":"created","comment":{"url":"https://api.github.com/repos/spotify/styx/pulls/comments/216178917","pull_request_review_id":153602503,"id":216178917,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIxNjE3ODkxNw==","diff_hunk":"@@ -0,0 +1,166 @@\n+/*\n+ * -\\-\\-\n+ * Spotify Styx Scheduler Service\n+ * --\n+ * Copyright (C) 2018 Spotify AB\n+ * --\n+ * Licensed under the Apache License, Version 2.0 (the \"License\");\n+ * you may not use this file except in compliance with the License.\n+ * You may obtain a copy of the License at\n+ * \n+ *      http://www.apache.org/licenses/LICENSE-2.0\n+ * \n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ * -/-/-\n+ */\n+\n+package com.spotify.styx.util;\n+\n+import static java.util.concurrent.TimeUnit.SECONDS;\n+import static org.hamcrest.Matchers.instanceOf;\n+import static org.hamcrest.Matchers.is;\n+import static org.junit.Assert.assertThat;\n+import static org.mockito.Mockito.verify;\n+\n+import com.google.common.collect.ImmutableList;\n+import io.grpc.Context;\n+import java.lang.reflect.Constructor;\n+import java.lang.reflect.InvocationTargetException;\n+import java.util.List;\n+import java.util.concurrent.Callable;\n+import java.util.concurrent.CompletableFuture;\n+import java.util.concurrent.ExecutorService;\n+import java.util.concurrent.Executors;\n+import java.util.concurrent.Future;\n+import java.util.concurrent.TimeUnit;\n+import java.util.function.Supplier;\n+import org.junit.Rule;\n+import org.junit.Test;\n+import org.junit.rules.ExpectedException;\n+import org.junit.runner.RunWith;\n+import org.mockito.Mock;\n+import org.mockito.runners.MockitoJUnitRunner;\n+\n+@RunWith(MockitoJUnitRunner.class)\n+public class GrpcContextUtilTest {\n+\n+  private static final Context.Key<String> TEST_KEY = Context.key(\"test\");\n+\n+  @Rule public ExpectedException exception = ExpectedException.none();\n+\n+  @Mock ExecutorService executorService;\n+\n+  private final ExecutorService sut = GrpcContextUtil.currentContextExecutorService(Executors.newCachedThreadPool());\n+\n+  @Test\n+  public void shouldForward() throws InterruptedException {\n+    final ExecutorService mockSut = GrpcContextUtil.currentContextExecutorService(executorService);\n+    mockSut.shutdown();\n+    verify(executorService).shutdown();\n+    mockSut.shutdownNow();\n+    verify(executorService).shutdownNow();\n+    mockSut.isShutdown();\n+    verify(executorService).isShutdown();\n+    mockSut.isTerminated();\n+    verify(executorService).isTerminated();\n+    mockSut.awaitTermination(7, TimeUnit.HOURS);\n+    verify(executorService).awaitTermination(7, TimeUnit.HOURS);\n+  }\n+\n+  @Test\n+  public void executeShouldPropagateContext() throws Exception {\n+    final CompletableFuture<String> value = new CompletableFuture<>();\n+    final Runnable runnable = () -> value.complete(TEST_KEY.get());\n+    Context.current().withValue(TEST_KEY, \"foobar\")\n+        .run(() -> sut.execute(runnable));\n+    assertThat(value.get(30, SECONDS), is(\"foobar\"));\n+  }\n+\n+  @Test\n+  public void submitRunnableShouldPropagateContext() throws Exception {\n+    final CompletableFuture<String> value = new CompletableFuture<>();\n+    final Runnable runnable = () -> value.complete(TEST_KEY.get());\n+    Context.current().withValue(TEST_KEY, \"foobar\")\n+        .run(() -> sut.submit(runnable));\n+    assertThat(value.get(30, SECONDS), is(\"foobar\"));\n+  }\n+\n+  @Test\n+  public void submitRunnableWithValueShouldPropagateContext() throws Exception {\n+    final CompletableFuture<String> value = new CompletableFuture<>();\n+    final Runnable runnable = () -> value.complete(TEST_KEY.get());\n+    Context.current().withValue(TEST_KEY, \"foobar\")\n+        .run(() -> sut.submit(runnable, \"quux\"));\n+    assertThat(value.get(30, SECONDS), is(\"foobar\"));\n+  }\n+\n+  @Test\n+  public void submitCallableShouldPropagateContext() throws Exception {\n+    final Callable<String> callable = TEST_KEY::get;\n+    final Future<String> value = Context.current().withValue(TEST_KEY, \"foobar\")\n+        .call(() -> sut.submit(callable));\n+    assertThat(value.get(30, SECONDS), is(\"foobar\"));\n+  }\n+\n+  @Test\n+  public void invokeAllShouldPropagateContext() throws Exception {\n+    final Callable<String> callable = TEST_KEY::get;\n+    final List<Future<String>> futures = Context.current().withValue(TEST_KEY, \"foobar\")\n+        .call(() -> sut.invokeAll(ImmutableList.of(callable)));\n+    assertThat(futures.get(0).get(30, SECONDS), is(\"foobar\"));\n+  }\n+\n+  @Test\n+  public void invokeAllWithTimeoutShouldPropagateContext() throws Exception {\n+    final Callable<String> callable = TEST_KEY::get;\n+    final List<Future<String>> futures = Context.current().withValue(TEST_KEY, \"foobar\")\n+        .call(() -> sut.invokeAll(ImmutableList.of(callable), 30, SECONDS));\n+    assertThat(futures.get(0).get(30, SECONDS), is(\"foobar\"));\n+  }\n+\n+  @Test\n+  public void invokeAnyShouldPropagateContext() throws Exception {\n+    final Callable<String> callable = TEST_KEY::get;\n+    final String result = Context.current().withValue(TEST_KEY, \"foobar\")\n+        .call(() -> sut.invokeAny(ImmutableList.of(callable)));\n+    assertThat(result, is(\"foobar\"));\n+  }\n+\n+  @Test\n+  public void invokeAnyWithTimeoutShouldPropagateContext() throws Exception {\n+    final Callable<String> callable = TEST_KEY::get;\n+    final String result = Context.current().withValue(TEST_KEY, \"foobar\")\n+        .call(() -> sut.invokeAny(ImmutableList.of(callable), 30, SECONDS));\n+    assertThat(result, is(\"foobar\"));\n+  }\n+\n+  @Test\n+  public void shouldPropagateContextForCfRunAsync() throws Exception {\n+    final CompletableFuture<String> value = new CompletableFuture<>();\n+    final Runnable runnable = () -> value.complete(TEST_KEY.get());\n+    Context.current().withValue(TEST_KEY, \"foobar\")\n+        .run(() -> CompletableFuture.runAsync(runnable, sut));\n+    assertThat(value.get(30, SECONDS), is(\"foobar\"));\n+  }\n+\n+  @Test\n+  public void shouldPropagateContextForCfSupplyAsync() throws Exception {\n+    final Supplier<String> get = TEST_KEY::get;\n+    final CompletableFuture<String> cf = Context.current().withValue(TEST_KEY, \"foobar\")\n+        .call(() -> CompletableFuture.supplyAsync(get, sut));\n+    assertThat(cf.get(30, SECONDS), is(\"foobar\"));\n+  }\n+\n+  @Test\n+  public void shouldNotBeConstructable() throws ReflectiveOperationException {\n+    final Constructor<GrpcContextUtil> constructor = GrpcContextUtil.class.getDeclaredConstructor();","path":"styx-common/src/test/java/com/spotify/styx/util/GrpcContextUtilTest.java","position":160,"original_position":160,"commit_id":"1da5681c027b149114d5ffa1dbba82e32e4ed8e9","original_commit_id":"1da5681c027b149114d5ffa1dbba82e32e4ed8e9","user":{"login":"danielnorberg","id":393289,"node_id":"MDQ6VXNlcjM5MzI4OQ==","avatar_url":"https://avatars1.githubusercontent.com/u/393289?v=4","gravatar_id":"","url":"https://api.github.com/users/danielnorberg","html_url":"https://github.com/danielnorberg","followers_url":"https://api.github.com/users/danielnorberg/followers","following_url":"https://api.github.com/users/danielnorberg/following{/other_user}","gists_url":"https://api.github.com/users/danielnorberg/gists{/gist_id}","starred_url":"https://api.github.com/users/danielnorberg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/danielnorberg/subscriptions","organizations_url":"https://api.github.com/users/danielnorberg/orgs","repos_url":"https://api.github.com/users/danielnorberg/repos","events_url":"https://api.github.com/users/danielnorberg/events{/privacy}","received_events_url":"https://api.github.com/users/danielnorberg/received_events","type":"User","site_admin":false},"body":"Yeah. We should have some reusable utility `verifyNotInstantiable(Class<?> cls)` method","created_at":"2018-09-10T01:09:45Z","updated_at":"2018-09-10T01:09:45Z","html_url":"https://github.com/spotify/styx/pull/554#discussion_r216178917","pull_request_url":"https://api.github.com/repos/spotify/styx/pulls/554","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/spotify/styx/pulls/comments/216178917"},"html":{"href":"https://github.com/spotify/styx/pull/554#discussion_r216178917"},"pull_request":{"href":"https://api.github.com/repos/spotify/styx/pulls/554"}},"in_reply_to_id":215548844},"pull_request":{"url":"https://api.github.com/repos/spotify/styx/pulls/554","id":209718056,"node_id":"MDExOlB1bGxSZXF1ZXN0MjA5NzE4MDU2","html_url":"https://github.com/spotify/styx/pull/554","diff_url":"https://github.com/spotify/styx/pull/554.diff","patch_url":"https://github.com/spotify/styx/pull/554.patch","issue_url":"https://api.github.com/repos/spotify/styx/issues/554","number":554,"state":"open","locked":false,"title":"k8s: optimize watcher","user":{"login":"danielnorberg","id":393289,"node_id":"MDQ6VXNlcjM5MzI4OQ==","avatar_url":"https://avatars1.githubusercontent.com/u/393289?v=4","gravatar_id":"","url":"https://api.github.com/users/danielnorberg","html_url":"https://github.com/danielnorberg","followers_url":"https://api.github.com/users/danielnorberg/followers","following_url":"https://api.github.com/users/danielnorberg/following{/other_user}","gists_url":"https://api.github.com/users/danielnorberg/gists{/gist_id}","starred_url":"https://api.github.com/users/danielnorberg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/danielnorberg/subscriptions","organizations_url":"https://api.github.com/users/danielnorberg/orgs","repos_url":"https://api.github.com/users/danielnorberg/repos","events_url":"https://api.github.com/users/danielnorberg/events{/privacy}","received_events_url":"https://api.github.com/users/danielnorberg/received_events","type":"User","site_admin":false},"body":"* Make pod watcher asynchronous to avoid falling behind and getting disconnected.\r\n* Let events for a pod coalesce in order to avoid re-processing for each small incremental pod update event.\r\n* Process pod update event batches on the same thread as the poller, eliminate race conditions.\r\n* Parallelize processing of pod update events to defeat IO latency.","created_at":"2018-08-21T06:12:51Z","updated_at":"2018-09-10T01:09:45Z","closed_at":null,"merged_at":null,"merge_commit_sha":"7d03f897b54cedb911328607ec43927fda09269c","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/spotify/styx/pulls/554/commits","review_comments_url":"https://api.github.com/repos/spotify/styx/pulls/554/comments","review_comment_url":"https://api.github.com/repos/spotify/styx/pulls/comments{/number}","comments_url":"https://api.github.com/repos/spotify/styx/issues/554/comments","statuses_url":"https://api.github.com/repos/spotify/styx/statuses/1da5681c027b149114d5ffa1dbba82e32e4ed8e9","head":{"label":"spotify:batch-k8s-pod-events","ref":"batch-k8s-pod-events","sha":"1da5681c027b149114d5ffa1dbba82e32e4ed8e9","user":{"login":"spotify","id":251374,"node_id":"MDEyOk9yZ2FuaXphdGlvbjI1MTM3NA==","avatar_url":"https://avatars2.githubusercontent.com/u/251374?v=4","gravatar_id":"","url":"https://api.github.com/users/spotify","html_url":"https://github.com/spotify","followers_url":"https://api.github.com/users/spotify/followers","following_url":"https://api.github.com/users/spotify/following{/other_user}","gists_url":"https://api.github.com/users/spotify/gists{/gist_id}","starred_url":"https://api.github.com/users/spotify/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/spotify/subscriptions","organizations_url":"https://api.github.com/users/spotify/orgs","repos_url":"https://api.github.com/users/spotify/repos","events_url":"https://api.github.com/users/spotify/events{/privacy}","received_events_url":"https://api.github.com/users/spotify/received_events","type":"Organization","site_admin":false},"repo":{"id":74431644,"node_id":"MDEwOlJlcG9zaXRvcnk3NDQzMTY0NA==","name":"styx","full_name":"spotify/styx","owner":{"login":"spotify","id":251374,"node_id":"MDEyOk9yZ2FuaXphdGlvbjI1MTM3NA==","avatar_url":"https://avatars2.githubusercontent.com/u/251374?v=4","gravatar_id":"","url":"https://api.github.com/users/spotify","html_url":"https://github.com/spotify","followers_url":"https://api.github.com/users/spotify/followers","following_url":"https://api.github.com/users/spotify/following{/other_user}","gists_url":"https://api.github.com/users/spotify/gists{/gist_id}","starred_url":"https://api.github.com/users/spotify/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/spotify/subscriptions","organizations_url":"https://api.github.com/users/spotify/orgs","repos_url":"https://api.github.com/users/spotify/repos","events_url":"https://api.github.com/users/spotify/events{/privacy}","received_events_url":"https://api.github.com/users/spotify/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/spotify/styx","description":"\"The path to execution\", Styx is a service that schedules batch data processing jobs in Docker containers on Kubernetes.","fork":false,"url":"https://api.github.com/repos/spotify/styx","forks_url":"https://api.github.com/repos/spotify/styx/forks","keys_url":"https://api.github.com/repos/spotify/styx/keys{/key_id}","collaborators_url":"https://api.github.com/repos/spotify/styx/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/spotify/styx/teams","hooks_url":"https://api.github.com/repos/spotify/styx/hooks","issue_events_url":"https://api.github.com/repos/spotify/styx/issues/events{/number}","events_url":"https://api.github.com/repos/spotify/styx/events","assignees_url":"https://api.github.com/repos/spotify/styx/assignees{/user}","branches_url":"https://api.github.com/repos/spotify/styx/branches{/branch}","tags_url":"https://api.github.com/repos/spotify/styx/tags","blobs_url":"https://api.github.com/repos/spotify/styx/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/spotify/styx/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/spotify/styx/git/refs{/sha}","trees_url":"https://api.github.com/repos/spotify/styx/git/trees{/sha}","statuses_url":"https://api.github.com/repos/spotify/styx/statuses/{sha}","languages_url":"https://api.github.com/repos/spotify/styx/languages","stargazers_url":"https://api.github.com/repos/spotify/styx/stargazers","contributors_url":"https://api.github.com/repos/spotify/styx/contributors","subscribers_url":"https://api.github.com/repos/spotify/styx/subscribers","subscription_url":"https://api.github.com/repos/spotify/styx/subscription","commits_url":"https://api.github.com/repos/spotify/styx/commits{/sha}","git_commits_url":"https://api.github.com/repos/spotify/styx/git/commits{/sha}","comments_url":"https://api.github.com/repos/spotify/styx/comments{/number}","issue_comment_url":"https://api.github.com/repos/spotify/styx/issues/comments{/number}","contents_url":"https://api.github.com/repos/spotify/styx/contents/{+path}","compare_url":"https://api.github.com/repos/spotify/styx/compare/{base}...{head}","merges_url":"https://api.github.com/repos/spotify/styx/merges","archive_url":"https://api.github.com/repos/spotify/styx/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/spotify/styx/downloads","issues_url":"https://api.github.com/repos/spotify/styx/issues{/number}","pulls_url":"https://api.github.com/repos/spotify/styx/pulls{/number}","milestones_url":"https://api.github.com/repos/spotify/styx/milestones{/number}","notifications_url":"https://api.github.com/repos/spotify/styx/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/spotify/styx/labels{/name}","releases_url":"https://api.github.com/repos/spotify/styx/releases{/id}","deployments_url":"https://api.github.com/repos/spotify/styx/deployments","created_at":"2016-11-22T03:44:55Z","updated_at":"2018-09-06T09:19:42Z","pushed_at":"2018-09-06T21:12:59Z","git_url":"git://github.com/spotify/styx.git","ssh_url":"git@github.com:spotify/styx.git","clone_url":"https://github.com/spotify/styx.git","svn_url":"https://github.com/spotify/styx","homepage":"","size":5813,"stargazers_count":111,"watchers_count":111,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":20,"mirror_url":null,"archived":false,"open_issues_count":21,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":20,"open_issues":21,"watchers":111,"default_branch":"master"}},"base":{"label":"spotify:master","ref":"master","sha":"43199ddbef39156a3722b21486127f3897b0b18f","user":{"login":"spotify","id":251374,"node_id":"MDEyOk9yZ2FuaXphdGlvbjI1MTM3NA==","avatar_url":"https://avatars2.githubusercontent.com/u/251374?v=4","gravatar_id":"","url":"https://api.github.com/users/spotify","html_url":"https://github.com/spotify","followers_url":"https://api.github.com/users/spotify/followers","following_url":"https://api.github.com/users/spotify/following{/other_user}","gists_url":"https://api.github.com/users/spotify/gists{/gist_id}","starred_url":"https://api.github.com/users/spotify/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/spotify/subscriptions","organizations_url":"https://api.github.com/users/spotify/orgs","repos_url":"https://api.github.com/users/spotify/repos","events_url":"https://api.github.com/users/spotify/events{/privacy}","received_events_url":"https://api.github.com/users/spotify/received_events","type":"Organization","site_admin":false},"repo":{"id":74431644,"node_id":"MDEwOlJlcG9zaXRvcnk3NDQzMTY0NA==","name":"styx","full_name":"spotify/styx","owner":{"login":"spotify","id":251374,"node_id":"MDEyOk9yZ2FuaXphdGlvbjI1MTM3NA==","avatar_url":"https://avatars2.githubusercontent.com/u/251374?v=4","gravatar_id":"","url":"https://api.github.com/users/spotify","html_url":"https://github.com/spotify","followers_url":"https://api.github.com/users/spotify/followers","following_url":"https://api.github.com/users/spotify/following{/other_user}","gists_url":"https://api.github.com/users/spotify/gists{/gist_id}","starred_url":"https://api.github.com/users/spotify/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/spotify/subscriptions","organizations_url":"https://api.github.com/users/spotify/orgs","repos_url":"https://api.github.com/users/spotify/repos","events_url":"https://api.github.com/users/spotify/events{/privacy}","received_events_url":"https://api.github.com/users/spotify/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/spotify/styx","description":"\"The path to execution\", Styx is a service that schedules batch data processing jobs in Docker containers on Kubernetes.","fork":false,"url":"https://api.github.com/repos/spotify/styx","forks_url":"https://api.github.com/repos/spotify/styx/forks","keys_url":"https://api.github.com/repos/spotify/styx/keys{/key_id}","collaborators_url":"https://api.github.com/repos/spotify/styx/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/spotify/styx/teams","hooks_url":"https://api.github.com/repos/spotify/styx/hooks","issue_events_url":"https://api.github.com/repos/spotify/styx/issues/events{/number}","events_url":"https://api.github.com/repos/spotify/styx/events","assignees_url":"https://api.github.com/repos/spotify/styx/assignees{/user}","branches_url":"https://api.github.com/repos/spotify/styx/branches{/branch}","tags_url":"https://api.github.com/repos/spotify/styx/tags","blobs_url":"https://api.github.com/repos/spotify/styx/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/spotify/styx/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/spotify/styx/git/refs{/sha}","trees_url":"https://api.github.com/repos/spotify/styx/git/trees{/sha}","statuses_url":"https://api.github.com/repos/spotify/styx/statuses/{sha}","languages_url":"https://api.github.com/repos/spotify/styx/languages","stargazers_url":"https://api.github.com/repos/spotify/styx/stargazers","contributors_url":"https://api.github.com/repos/spotify/styx/contributors","subscribers_url":"https://api.github.com/repos/spotify/styx/subscribers","subscription_url":"https://api.github.com/repos/spotify/styx/subscription","commits_url":"https://api.github.com/repos/spotify/styx/commits{/sha}","git_commits_url":"https://api.github.com/repos/spotify/styx/git/commits{/sha}","comments_url":"https://api.github.com/repos/spotify/styx/comments{/number}","issue_comment_url":"https://api.github.com/repos/spotify/styx/issues/comments{/number}","contents_url":"https://api.github.com/repos/spotify/styx/contents/{+path}","compare_url":"https://api.github.com/repos/spotify/styx/compare/{base}...{head}","merges_url":"https://api.github.com/repos/spotify/styx/merges","archive_url":"https://api.github.com/repos/spotify/styx/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/spotify/styx/downloads","issues_url":"https://api.github.com/repos/spotify/styx/issues{/number}","pulls_url":"https://api.github.com/repos/spotify/styx/pulls{/number}","milestones_url":"https://api.github.com/repos/spotify/styx/milestones{/number}","notifications_url":"https://api.github.com/repos/spotify/styx/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/spotify/styx/labels{/name}","releases_url":"https://api.github.com/repos/spotify/styx/releases{/id}","deployments_url":"https://api.github.com/repos/spotify/styx/deployments","created_at":"2016-11-22T03:44:55Z","updated_at":"2018-09-06T09:19:42Z","pushed_at":"2018-09-06T21:12:59Z","git_url":"git://github.com/spotify/styx.git","ssh_url":"git@github.com:spotify/styx.git","clone_url":"https://github.com/spotify/styx.git","svn_url":"https://github.com/spotify/styx","homepage":"","size":5813,"stargazers_count":111,"watchers_count":111,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":20,"mirror_url":null,"archived":false,"open_issues_count":21,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":20,"open_issues":21,"watchers":111,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/spotify/styx/pulls/554"},"html":{"href":"https://github.com/spotify/styx/pull/554"},"issue":{"href":"https://api.github.com/repos/spotify/styx/issues/554"},"comments":{"href":"https://api.github.com/repos/spotify/styx/issues/554/comments"},"review_comments":{"href":"https://api.github.com/repos/spotify/styx/pulls/554/comments"},"review_comment":{"href":"https://api.github.com/repos/spotify/styx/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/spotify/styx/pulls/554/commits"},"statuses":{"href":"https://api.github.com/repos/spotify/styx/statuses/1da5681c027b149114d5ffa1dbba82e32e4ed8e9"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"danielnorberg"}}