{"action":"created","comment":{"url":"https://api.github.com/repos/linkedin/ambry/pulls/comments/86053782","pull_request_review_id":6731855,"id":86053782,"diff_hunk":"@@ -0,0 +1,168 @@\n+/*\n+ * Copyright 2016 LinkedIn Corp. All rights reserved.\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+ */\n+\n+package com.github.ambry.store;\n+\n+import com.codahale.metrics.Timer;\n+import com.github.ambry.clustermap.DiskId;\n+import com.github.ambry.clustermap.PartitionId;\n+import com.github.ambry.clustermap.ReplicaId;\n+import com.github.ambry.config.StoreConfig;\n+import com.github.ambry.store.StoreMetrics.DiskLevelMetrics;\n+import com.github.ambry.utils.Time;\n+import com.github.ambry.utils.Utils;\n+import java.io.File;\n+import java.util.HashMap;\n+import java.util.List;\n+import java.util.Map;\n+import java.util.concurrent.ConcurrentHashMap;\n+import java.util.concurrent.ConcurrentMap;\n+import java.util.concurrent.ScheduledExecutorService;\n+import org.slf4j.Logger;\n+import org.slf4j.LoggerFactory;\n+\n+\n+/**\n+ * Manages all the stores on a disk.\n+ */\n+class DiskManager {\n+  private final ConcurrentMap<PartitionId, BlobStore> stores = new ConcurrentHashMap<>();\n+  private final DiskId disk;\n+  private final StoreConfig config;\n+  private final DiskLevelMetrics metrics;\n+\n+  private static final Logger logger = LoggerFactory.getLogger(DiskManager.class);\n+\n+  /**\n+   * Constructs a {@link DiskManager}\n+   * @param disk representation of the disk.\n+   * @param replicas all the replicas on this disk.\n+   * @param config the settings for store configuration.\n+   * @param scheduler the {@link ScheduledExecutorService} for executing background tasks.\n+   * @param storeMetrics the {@link StoreMetrics} object used for store-related metrics.\n+   * @param keyFactory the {@link StoreKeyFactory} for parsing store keys.\n+   * @param recovery the {@link MessageStoreRecovery} instance to use.\n+   * @param hardDelete the {@link MessageStoreHardDelete} instance to use.\n+   * @param time the {@link Time} instance to use.\n+   */\n+  DiskManager(DiskId disk, List<ReplicaId> replicas, StoreConfig config, ScheduledExecutorService scheduler,\n+      StoreMetrics storeMetrics, StoreKeyFactory keyFactory, MessageStoreRecovery recovery,\n+      MessageStoreHardDelete hardDelete, Time time) {\n+    this.disk = disk;\n+    this.config = config;\n+    this.metrics = storeMetrics.createDiskLevelMetrics(disk.getMountPath());\n+    DiskIOScheduler ioScheduler = new DiskIOScheduler(null);\n+    for (ReplicaId replica : replicas) {\n+      if (disk.equals(replica.getDiskId())) {\n+        String storeId = replica.getPartitionId().toString();\n+        BlobStore store = new BlobStore(storeId, config, scheduler, ioScheduler, metrics, replica.getReplicaPath(),\n+            replica.getCapacityInBytes(), keyFactory, recovery, hardDelete, time);\n+        stores.put(replica.getPartitionId(), store);\n+      }\n+    }\n+  }\n+\n+  /**\n+   * Starts all the stores on this disk.\n+   */\n+  void start()\n+      throws InterruptedException {\n+    Timer.Context context = metrics.diskStartTime.time();\n+    try {\n+      File mountPath = new File(disk.getMountPath());\n+      if (mountPath.exists()) {\n+        Map<StoreStarter, Thread> startupThreads = new HashMap<>();\n+        for (final Map.Entry<PartitionId, BlobStore> partitionAndStore : stores.entrySet()) {\n+          StoreStarter storeStarter = new StoreStarter(partitionAndStore.getKey(), partitionAndStore.getValue());\n+          Thread thread = Utils.newThread(\"store-startup-\" + partitionAndStore.getKey(), storeStarter, false);\n+          thread.start();\n+          startupThreads.put(storeStarter, thread);\n+        }\n+        int numFailed = 0;\n+        for (Map.Entry<StoreStarter, Thread> starterAndThread : startupThreads.entrySet()) {\n+          starterAndThread.getValue().join();\n+          Exception exception = starterAndThread.getKey().exception;\n+          if (exception != null) {\n+            numFailed++;\n+            logger.error(\"Exception while starting store for the partition\" + starterAndThread.getKey().partition,\n+                exception);\n+          }\n+        }\n+        if (numFailed > 0) {\n+          metrics.diskStartFailure.inc();\n+          logger.error(\"Could not start \" + numFailed + \" out of \" + stores.size() + \" stores on the disk \" + disk);\n+        }\n+      } else {\n+        metrics.diskStartFailure.inc();\n+        logger.error(\"Mount path does not exist: \" + mountPath + \" ; cannot start stores on this disk\");\n+      }\n+    } finally {\n+      context.stop();\n+    }\n+  }\n+\n+  /**\n+   * Shuts down all the stores this disk.\n+   */\n+  void shutdown() {\n+    for (Map.Entry<PartitionId, BlobStore> partitionAndStore : stores.entrySet()) {\n+      try {\n+        partitionAndStore.getValue().shutdown();\n+      } catch (Exception e) {\n+        logger.error(\n+            \"Exception while shutting down store for partition \" + partitionAndStore.getKey() + \" on disk \" + disk);\n+      }\n+    }\n+  }\n+\n+  /**\n+   * @param id the {@link PartitionId} to find the store for.\n+   * @return the associated {@link Store}, or {@code null} if the partition is not on this disk, or the store is not\n+   *         started.\n+   */\n+  Store getStore(PartitionId id) {\n+    BlobStore store = stores.get(id);\n+    return store.isStarted() ? store : null;\n+  }\n+\n+  /**\n+   * @return the {@link DiskId} that is managed by this {@link DiskManager}.\n+   */\n+  DiskId getDisk() {\n+    return disk;\n+  }\n+\n+  /**\n+   * A {@link Runnable} that starts a {@link Store} and saves a reference to an exception if starting failed.\n+   */\n+  private class StoreStarter implements Runnable {\n+    final PartitionId partition;\n+    final Store store;\n+    volatile Exception exception = null;\n+\n+    public StoreStarter(PartitionId partition, Store store) {\n+      this.partition = partition;\n+      this.store = store;\n+    }\n+\n+    @Override\n+    public void run() {\n+      try {\n+        store.start();\n+      } catch (StoreException e) {","path":"ambry-store/src/main/java/com.github.ambry.store/DiskManager.java","position":null,"original_position":163,"commit_id":"74bfc87dfce8c2f371e1d5bae6aad9c56ad15cf2","original_commit_id":"0125673602726fab297837ed983676238fcf9288","user":{"login":"cgtz","id":3821381,"avatar_url":"https://avatars.githubusercontent.com/u/3821381?v=3","gravatar_id":"","url":"https://api.github.com/users/cgtz","html_url":"https://github.com/cgtz","followers_url":"https://api.github.com/users/cgtz/followers","following_url":"https://api.github.com/users/cgtz/following{/other_user}","gists_url":"https://api.github.com/users/cgtz/gists{/gist_id}","starred_url":"https://api.github.com/users/cgtz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cgtz/subscriptions","organizations_url":"https://api.github.com/users/cgtz/orgs","repos_url":"https://api.github.com/users/cgtz/repos","events_url":"https://api.github.com/users/cgtz/events{/privacy}","received_events_url":"https://api.github.com/users/cgtz/received_events","type":"User","site_admin":false},"body":"Changed to catch all exceptions.","created_at":"2016-11-02T00:26:28Z","updated_at":"2016-11-02T00:26:28Z","html_url":"https://github.com/linkedin/ambry/pull/474#discussion_r86053782","pull_request_url":"https://api.github.com/repos/linkedin/ambry/pulls/474","_links":{"self":{"href":"https://api.github.com/repos/linkedin/ambry/pulls/comments/86053782"},"html":{"href":"https://github.com/linkedin/ambry/pull/474#discussion_r86053782"},"pull_request":{"href":"https://api.github.com/repos/linkedin/ambry/pulls/474"}}},"pull_request":{"url":"https://api.github.com/repos/linkedin/ambry/pulls/474","id":90858276,"html_url":"https://github.com/linkedin/ambry/pull/474","diff_url":"https://github.com/linkedin/ambry/pull/474.diff","patch_url":"https://github.com/linkedin/ambry/pull/474.patch","issue_url":"https://api.github.com/repos/linkedin/ambry/issues/474","number":474,"state":"open","locked":false,"title":"Adding DiskManager and DiskIOScheduler","user":{"login":"cgtz","id":3821381,"avatar_url":"https://avatars.githubusercontent.com/u/3821381?v=3","gravatar_id":"","url":"https://api.github.com/users/cgtz","html_url":"https://github.com/cgtz","followers_url":"https://api.github.com/users/cgtz/followers","following_url":"https://api.github.com/users/cgtz/following{/other_user}","gists_url":"https://api.github.com/users/cgtz/gists{/gist_id}","starred_url":"https://api.github.com/users/cgtz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cgtz/subscriptions","organizations_url":"https://api.github.com/users/cgtz/orgs","repos_url":"https://api.github.com/users/cgtz/repos","events_url":"https://api.github.com/users/cgtz/events{/privacy}","received_events_url":"https://api.github.com/users/cgtz/received_events","type":"User","site_admin":false},"body":"- Modifying StoreManager to instantiate a DiskManager for each disk on\n  the node.\n- Adding a DiskManager that manages all of the stores on a certain disk\n- Adding a basic DiskIOScheduler class that is passed into each\n  BlobStore instance. It is not yet used.\n- Adding support for parallel startup of disks with configurable disk\n  and store level parallelism.\n- Allowing store startup to still succeed even when individual stores\n  fail to start up.\n\n**Time:** 45 min.\n\n**Reviewers:** @vgkholla, @nsivabalan \n\n**Coverage:**\n\n| Class | Class, % | Method, % | Line, % |\n| --- | --- | --- | --- |\n| DiskIOScheduler | 100% (1/ 1) | 100% (3/ 3) | 100% (11/ 11) |\n| DiskManager | 100% (2/ 2) | 100% (8/ 8) | 92.5% (49/ 53) |\n| StoreManager | 100% (2/ 2) | 100% (8/ 8) | 93.5% (58/ 62) |\n","created_at":"2016-10-25T17:53:22Z","updated_at":"2016-11-02T00:26:28Z","closed_at":null,"merged_at":null,"merge_commit_sha":"95521a9be3e942b904d12a9b56fe44d6ad1b4c05","assignee":{"login":"vgkholla","id":288834,"avatar_url":"https://avatars.githubusercontent.com/u/288834?v=3","gravatar_id":"","url":"https://api.github.com/users/vgkholla","html_url":"https://github.com/vgkholla","followers_url":"https://api.github.com/users/vgkholla/followers","following_url":"https://api.github.com/users/vgkholla/following{/other_user}","gists_url":"https://api.github.com/users/vgkholla/gists{/gist_id}","starred_url":"https://api.github.com/users/vgkholla/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vgkholla/subscriptions","organizations_url":"https://api.github.com/users/vgkholla/orgs","repos_url":"https://api.github.com/users/vgkholla/repos","events_url":"https://api.github.com/users/vgkholla/events{/privacy}","received_events_url":"https://api.github.com/users/vgkholla/received_events","type":"User","site_admin":false},"assignees":[{"login":"vgkholla","id":288834,"avatar_url":"https://avatars.githubusercontent.com/u/288834?v=3","gravatar_id":"","url":"https://api.github.com/users/vgkholla","html_url":"https://github.com/vgkholla","followers_url":"https://api.github.com/users/vgkholla/followers","following_url":"https://api.github.com/users/vgkholla/following{/other_user}","gists_url":"https://api.github.com/users/vgkholla/gists{/gist_id}","starred_url":"https://api.github.com/users/vgkholla/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vgkholla/subscriptions","organizations_url":"https://api.github.com/users/vgkholla/orgs","repos_url":"https://api.github.com/users/vgkholla/repos","events_url":"https://api.github.com/users/vgkholla/events{/privacy}","received_events_url":"https://api.github.com/users/vgkholla/received_events","type":"User","site_admin":false},{"login":"nsivabalan","id":513218,"avatar_url":"https://avatars.githubusercontent.com/u/513218?v=3","gravatar_id":"","url":"https://api.github.com/users/nsivabalan","html_url":"https://github.com/nsivabalan","followers_url":"https://api.github.com/users/nsivabalan/followers","following_url":"https://api.github.com/users/nsivabalan/following{/other_user}","gists_url":"https://api.github.com/users/nsivabalan/gists{/gist_id}","starred_url":"https://api.github.com/users/nsivabalan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nsivabalan/subscriptions","organizations_url":"https://api.github.com/users/nsivabalan/orgs","repos_url":"https://api.github.com/users/nsivabalan/repos","events_url":"https://api.github.com/users/nsivabalan/events{/privacy}","received_events_url":"https://api.github.com/users/nsivabalan/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/linkedin/ambry/pulls/474/commits","review_comments_url":"https://api.github.com/repos/linkedin/ambry/pulls/474/comments","review_comment_url":"https://api.github.com/repos/linkedin/ambry/pulls/comments{/number}","comments_url":"https://api.github.com/repos/linkedin/ambry/issues/474/comments","statuses_url":"https://api.github.com/repos/linkedin/ambry/statuses/74bfc87dfce8c2f371e1d5bae6aad9c56ad15cf2","head":{"label":"cgtz:disk-manager","ref":"disk-manager","sha":"74bfc87dfce8c2f371e1d5bae6aad9c56ad15cf2","user":{"login":"cgtz","id":3821381,"avatar_url":"https://avatars.githubusercontent.com/u/3821381?v=3","gravatar_id":"","url":"https://api.github.com/users/cgtz","html_url":"https://github.com/cgtz","followers_url":"https://api.github.com/users/cgtz/followers","following_url":"https://api.github.com/users/cgtz/following{/other_user}","gists_url":"https://api.github.com/users/cgtz/gists{/gist_id}","starred_url":"https://api.github.com/users/cgtz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cgtz/subscriptions","organizations_url":"https://api.github.com/users/cgtz/orgs","repos_url":"https://api.github.com/users/cgtz/repos","events_url":"https://api.github.com/users/cgtz/events{/privacy}","received_events_url":"https://api.github.com/users/cgtz/received_events","type":"User","site_admin":false},"repo":{"id":54433244,"name":"ambry","full_name":"cgtz/ambry","owner":{"login":"cgtz","id":3821381,"avatar_url":"https://avatars.githubusercontent.com/u/3821381?v=3","gravatar_id":"","url":"https://api.github.com/users/cgtz","html_url":"https://github.com/cgtz","followers_url":"https://api.github.com/users/cgtz/followers","following_url":"https://api.github.com/users/cgtz/following{/other_user}","gists_url":"https://api.github.com/users/cgtz/gists{/gist_id}","starred_url":"https://api.github.com/users/cgtz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cgtz/subscriptions","organizations_url":"https://api.github.com/users/cgtz/orgs","repos_url":"https://api.github.com/users/cgtz/repos","events_url":"https://api.github.com/users/cgtz/events{/privacy}","received_events_url":"https://api.github.com/users/cgtz/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/cgtz/ambry","description":"Immutable blob store","fork":true,"url":"https://api.github.com/repos/cgtz/ambry","forks_url":"https://api.github.com/repos/cgtz/ambry/forks","keys_url":"https://api.github.com/repos/cgtz/ambry/keys{/key_id}","collaborators_url":"https://api.github.com/repos/cgtz/ambry/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/cgtz/ambry/teams","hooks_url":"https://api.github.com/repos/cgtz/ambry/hooks","issue_events_url":"https://api.github.com/repos/cgtz/ambry/issues/events{/number}","events_url":"https://api.github.com/repos/cgtz/ambry/events","assignees_url":"https://api.github.com/repos/cgtz/ambry/assignees{/user}","branches_url":"https://api.github.com/repos/cgtz/ambry/branches{/branch}","tags_url":"https://api.github.com/repos/cgtz/ambry/tags","blobs_url":"https://api.github.com/repos/cgtz/ambry/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/cgtz/ambry/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/cgtz/ambry/git/refs{/sha}","trees_url":"https://api.github.com/repos/cgtz/ambry/git/trees{/sha}","statuses_url":"https://api.github.com/repos/cgtz/ambry/statuses/{sha}","languages_url":"https://api.github.com/repos/cgtz/ambry/languages","stargazers_url":"https://api.github.com/repos/cgtz/ambry/stargazers","contributors_url":"https://api.github.com/repos/cgtz/ambry/contributors","subscribers_url":"https://api.github.com/repos/cgtz/ambry/subscribers","subscription_url":"https://api.github.com/repos/cgtz/ambry/subscription","commits_url":"https://api.github.com/repos/cgtz/ambry/commits{/sha}","git_commits_url":"https://api.github.com/repos/cgtz/ambry/git/commits{/sha}","comments_url":"https://api.github.com/repos/cgtz/ambry/comments{/number}","issue_comment_url":"https://api.github.com/repos/cgtz/ambry/issues/comments{/number}","contents_url":"https://api.github.com/repos/cgtz/ambry/contents/{+path}","compare_url":"https://api.github.com/repos/cgtz/ambry/compare/{base}...{head}","merges_url":"https://api.github.com/repos/cgtz/ambry/merges","archive_url":"https://api.github.com/repos/cgtz/ambry/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/cgtz/ambry/downloads","issues_url":"https://api.github.com/repos/cgtz/ambry/issues{/number}","pulls_url":"https://api.github.com/repos/cgtz/ambry/pulls{/number}","milestones_url":"https://api.github.com/repos/cgtz/ambry/milestones{/number}","notifications_url":"https://api.github.com/repos/cgtz/ambry/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/cgtz/ambry/labels{/name}","releases_url":"https://api.github.com/repos/cgtz/ambry/releases{/id}","deployments_url":"https://api.github.com/repos/cgtz/ambry/deployments","created_at":"2016-03-22T00:38:34Z","updated_at":"2016-10-25T17:05:43Z","pushed_at":"2016-11-02T00:25:57Z","git_url":"git://github.com/cgtz/ambry.git","ssh_url":"git@github.com:cgtz/ambry.git","clone_url":"https://github.com/cgtz/ambry.git","svn_url":"https://github.com/cgtz/ambry","homepage":null,"size":7797,"stargazers_count":0,"watchers_count":0,"language":"Java","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":"linkedin:master","ref":"master","sha":"6913392bb5346657d0b33f2de22f5bd1ddc987a3","user":{"login":"linkedin","id":357098,"avatar_url":"https://avatars.githubusercontent.com/u/357098?v=3","gravatar_id":"","url":"https://api.github.com/users/linkedin","html_url":"https://github.com/linkedin","followers_url":"https://api.github.com/users/linkedin/followers","following_url":"https://api.github.com/users/linkedin/following{/other_user}","gists_url":"https://api.github.com/users/linkedin/gists{/gist_id}","starred_url":"https://api.github.com/users/linkedin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/linkedin/subscriptions","organizations_url":"https://api.github.com/users/linkedin/orgs","repos_url":"https://api.github.com/users/linkedin/repos","events_url":"https://api.github.com/users/linkedin/events{/privacy}","received_events_url":"https://api.github.com/users/linkedin/received_events","type":"Organization","site_admin":false},"repo":{"id":13870893,"name":"ambry","full_name":"linkedin/ambry","owner":{"login":"linkedin","id":357098,"avatar_url":"https://avatars.githubusercontent.com/u/357098?v=3","gravatar_id":"","url":"https://api.github.com/users/linkedin","html_url":"https://github.com/linkedin","followers_url":"https://api.github.com/users/linkedin/followers","following_url":"https://api.github.com/users/linkedin/following{/other_user}","gists_url":"https://api.github.com/users/linkedin/gists{/gist_id}","starred_url":"https://api.github.com/users/linkedin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/linkedin/subscriptions","organizations_url":"https://api.github.com/users/linkedin/orgs","repos_url":"https://api.github.com/users/linkedin/repos","events_url":"https://api.github.com/users/linkedin/events{/privacy}","received_events_url":"https://api.github.com/users/linkedin/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/linkedin/ambry","description":"Distributed object store","fork":false,"url":"https://api.github.com/repos/linkedin/ambry","forks_url":"https://api.github.com/repos/linkedin/ambry/forks","keys_url":"https://api.github.com/repos/linkedin/ambry/keys{/key_id}","collaborators_url":"https://api.github.com/repos/linkedin/ambry/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/linkedin/ambry/teams","hooks_url":"https://api.github.com/repos/linkedin/ambry/hooks","issue_events_url":"https://api.github.com/repos/linkedin/ambry/issues/events{/number}","events_url":"https://api.github.com/repos/linkedin/ambry/events","assignees_url":"https://api.github.com/repos/linkedin/ambry/assignees{/user}","branches_url":"https://api.github.com/repos/linkedin/ambry/branches{/branch}","tags_url":"https://api.github.com/repos/linkedin/ambry/tags","blobs_url":"https://api.github.com/repos/linkedin/ambry/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/linkedin/ambry/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/linkedin/ambry/git/refs{/sha}","trees_url":"https://api.github.com/repos/linkedin/ambry/git/trees{/sha}","statuses_url":"https://api.github.com/repos/linkedin/ambry/statuses/{sha}","languages_url":"https://api.github.com/repos/linkedin/ambry/languages","stargazers_url":"https://api.github.com/repos/linkedin/ambry/stargazers","contributors_url":"https://api.github.com/repos/linkedin/ambry/contributors","subscribers_url":"https://api.github.com/repos/linkedin/ambry/subscribers","subscription_url":"https://api.github.com/repos/linkedin/ambry/subscription","commits_url":"https://api.github.com/repos/linkedin/ambry/commits{/sha}","git_commits_url":"https://api.github.com/repos/linkedin/ambry/git/commits{/sha}","comments_url":"https://api.github.com/repos/linkedin/ambry/comments{/number}","issue_comment_url":"https://api.github.com/repos/linkedin/ambry/issues/comments{/number}","contents_url":"https://api.github.com/repos/linkedin/ambry/contents/{+path}","compare_url":"https://api.github.com/repos/linkedin/ambry/compare/{base}...{head}","merges_url":"https://api.github.com/repos/linkedin/ambry/merges","archive_url":"https://api.github.com/repos/linkedin/ambry/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/linkedin/ambry/downloads","issues_url":"https://api.github.com/repos/linkedin/ambry/issues{/number}","pulls_url":"https://api.github.com/repos/linkedin/ambry/pulls{/number}","milestones_url":"https://api.github.com/repos/linkedin/ambry/milestones{/number}","notifications_url":"https://api.github.com/repos/linkedin/ambry/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/linkedin/ambry/labels{/name}","releases_url":"https://api.github.com/repos/linkedin/ambry/releases{/id}","deployments_url":"https://api.github.com/repos/linkedin/ambry/deployments","created_at":"2013-10-25T20:04:54Z","updated_at":"2016-10-31T09:36:19Z","pushed_at":"2016-11-02T00:25:58Z","git_url":"git://github.com/linkedin/ambry.git","ssh_url":"git@github.com:linkedin/ambry.git","clone_url":"https://github.com/linkedin/ambry.git","svn_url":"https://github.com/linkedin/ambry","homepage":"https://github.com/linkedin/ambry/wiki","size":9135,"stargazers_count":751,"watchers_count":751,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":117,"mirror_url":null,"open_issues_count":44,"forks":117,"open_issues":44,"watchers":751,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/linkedin/ambry/pulls/474"},"html":{"href":"https://github.com/linkedin/ambry/pull/474"},"issue":{"href":"https://api.github.com/repos/linkedin/ambry/issues/474"},"comments":{"href":"https://api.github.com/repos/linkedin/ambry/issues/474/comments"},"review_comments":{"href":"https://api.github.com/repos/linkedin/ambry/pulls/474/comments"},"review_comment":{"href":"https://api.github.com/repos/linkedin/ambry/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/linkedin/ambry/pulls/474/commits"},"statuses":{"href":"https://api.github.com/repos/linkedin/ambry/statuses/74bfc87dfce8c2f371e1d5bae6aad9c56ad15cf2"}}}}
{"actor":{"display_login":"cgtz"}}