{"action":"created","comment":{"url":"https://api.github.com/repos/elastic/elasticsearch/pulls/comments/88696797","pull_request_review_id":9264885,"id":88696797,"diff_hunk":"@@ -132,59 +146,154 @@ public UnicastZenPing(Settings settings, ThreadPool threadPool, TransportService\n         this.hostsProvider = unicastHostsProvider;\n \n         this.concurrentConnects = DISCOVERY_ZEN_PING_UNICAST_CONCURRENT_CONNECTS_SETTING.get(settings);\n-        List<String> hosts = DISCOVERY_ZEN_PING_UNICAST_HOSTS_SETTING.get(settings);\n-        final int limitPortCounts;\n+        final List<String> hosts = DISCOVERY_ZEN_PING_UNICAST_HOSTS_SETTING.get(settings);\n         if (hosts.isEmpty()) {\n             // if unicast hosts are not specified, fill with simple defaults on the local machine\n+            configuredHosts = transportService.getLocalAddresses();\n             limitPortCounts = LIMIT_LOCAL_PORTS_COUNT;\n-            hosts.addAll(transportService.getLocalAddresses());\n         } else {\n+            configuredHosts = hosts;\n             // we only limit to 1 addresses, makes no sense to ping 100 ports\n             limitPortCounts = LIMIT_FOREIGN_PORTS_COUNT;\n         }\n-\n-        logger.debug(\"using initial hosts {}, with concurrent_connects [{}]\", hosts, concurrentConnects);\n-        List<DiscoveryNode> configuredTargetNodes = new ArrayList<>();\n-        for (final String host : hosts) {\n-            configuredTargetNodes.addAll(resolveDiscoveryNodes(host, limitPortCounts, transportService,\n-                () -> UNICAST_NODE_PREFIX + unicastNodeIdGenerator.incrementAndGet() + \"#\"));\n-        }\n-        this.configuredTargetNodes = configuredTargetNodes.toArray(new DiscoveryNode[configuredTargetNodes.size()]);\n+        logger.debug(\"using initial hosts {}, with concurrent_connects [{}]\", configuredHosts, concurrentConnects);\n \n         transportService.registerRequestHandler(ACTION_NAME, UnicastPingRequest::new, ThreadPool.Names.SAME,\n                 new UnicastPingRequestHandler());\n \n         ThreadFactory threadFactory = EsExecutors.daemonThreadFactory(settings, \"[unicast_connect]\");\n         unicastConnectExecutor = EsExecutors.newScaling(\"unicast_connect\", 0, concurrentConnects, 60, TimeUnit.SECONDS,\n                 threadFactory, threadPool.getThreadContext());\n+\n+        resolveTimeout = DISCOVERY_ZEN_PING_UNICAST_HOSTS_RESOLVE_TIMEOUT.get(settings);\n+    }\n+\n+    private static class ResolvedHostname {\n+\n+        private final TransportAddress[] addresses;\n+        private final UnknownHostException failure;\n+\n+        public static ResolvedHostname success(final TransportAddress[] addresses) {\n+            return new ResolvedHostname(addresses, null);\n+        }\n+\n+        public static ResolvedHostname failure(final UnknownHostException failure) {\n+            return new ResolvedHostname(null, failure);\n+        }\n+\n+        private ResolvedHostname(final TransportAddress[] addresses, UnknownHostException failure) {\n+            assert addresses != null && failure == null || addresses == null && failure != null;\n+            this.addresses = addresses;\n+            this.failure = failure;\n+        }\n+\n+        public boolean isSuccess() {\n+            return addresses != null;\n+        }\n+\n+        public TransportAddress[] addresses() {\n+            return addresses;\n+        }\n+\n+        public UnknownHostException failure() {\n+            assert !isSuccess();\n+            return failure;\n+        }\n+\n     }\n \n     /**\n-     * Resolves a host to a list of discovery nodes.  The host is resolved into a transport\n-     * address (or a collection of addresses if the number of ports is greater than one) and\n-     * the transport addresses are used to created discovery nodes.\n+     * Resolves a list of hosts to a list of discovery nodes. Each host is resolved into a transport address (or a collection of addresses\n+     * if the number of ports is greater than one) and the transport addresses are used to created discovery nodes. Host lookups are done\n+     * in parallel using the generic thread pool from the specified thread pool up to the specified resolve timeout.\n      *\n-     * @param host the host to resolve\n-     * @param limitPortCounts the number of ports to resolve (should be 1 for non-local transport)\n+     * @param threadPool       the thread pool used to parallelize hostname lookups\n+     * @param logger           logger used for logging messages regarding hostname lookups\n+     * @param hosts            the hosts to resolve\n+     * @param limitPortCounts  the number of ports to resolve (should be 1 for non-local transport)\n      * @param transportService the transport service\n-     * @param idGenerator the generator to supply unique ids for each discovery node\n+     * @param idGenerator      the generator to supply unique ids for each discovery node\n+     * @param resolveTimeout   the timeout before returning from hostname lookups\n      * @return a list of discovery nodes with resolved transport addresses\n      */\n-    public static List<DiscoveryNode> resolveDiscoveryNodes(final String host, final int limitPortCounts,\n-                                                            final TransportService transportService, final Supplier<String> idGenerator) {\n-        List<DiscoveryNode> discoveryNodes = new ArrayList<>();\n-        try {\n-            TransportAddress[] addresses = transportService.addressesFromString(host, limitPortCounts);\n-            for (TransportAddress address : addresses) {\n-                discoveryNodes.add(new DiscoveryNode(idGenerator.get(), address, emptyMap(), emptySet(),\n-                                                        Version.CURRENT.minimumCompatibilityVersion()));\n+    public static List<DiscoveryNode> resolveDiscoveryNodes(\n+        final ThreadPool threadPool,\n+        final Logger logger,\n+        final List<String> hosts,\n+        final int limitPortCounts,\n+        final TransportService transportService,\n+        final Supplier<String> idGenerator,\n+        final TimeValue resolveTimeout) throws InterruptedException {\n+        Objects.requireNonNull(threadPool);\n+        Objects.requireNonNull(logger);\n+        Objects.requireNonNull(hosts);\n+        Objects.requireNonNull(transportService);\n+        Objects.requireNonNull(idGenerator);\n+        Objects.requireNonNull(resolveTimeout);\n+        if (resolveTimeout.nanos() <= 0) {\n+            throw new IllegalArgumentException(\"resolve timeout must be positive but was [\" + resolveTimeout + \"]\");\n+        }\n+        // create tasks to submit to the executor service; we will wait up to resolveTimeout for these tasks to complete\n+        final List<Callable<ResolvedHostname>> callables =\n+            hosts.stream().map(hn -> lookup(hn, transportService, limitPortCounts)).collect(Collectors.toList());\n+        final List<Future<ResolvedHostname>> futures =\n+            threadPool.generic().invokeAll(callables, resolveTimeout.nanos(), TimeUnit.NANOSECONDS);","path":"core/src/main/java/org/elasticsearch/discovery/zen/UnicastZenPing.java","position":200,"original_position":196,"commit_id":"4868321727293ea3edf11dd6b3aabe6b3d75387c","original_commit_id":"acdc4bc890088d34e43e4ff1f04e323b5629d0e6","user":{"login":"rjernst","id":289412,"avatar_url":"https://avatars.githubusercontent.com/u/289412?v=3","gravatar_id":"","url":"https://api.github.com/users/rjernst","html_url":"https://github.com/rjernst","followers_url":"https://api.github.com/users/rjernst/followers","following_url":"https://api.github.com/users/rjernst/following{/other_user}","gists_url":"https://api.github.com/users/rjernst/gists{/gist_id}","starred_url":"https://api.github.com/users/rjernst/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rjernst/subscriptions","organizations_url":"https://api.github.com/users/rjernst/orgs","repos_url":"https://api.github.com/users/rjernst/repos","events_url":"https://api.github.com/users/rjernst/events{/privacy}","received_events_url":"https://api.github.com/users/rjernst/received_events","type":"User","site_admin":false},"body":"Actually plugins can implement `Closeable` and they will be closed when the node shuts down.","created_at":"2016-11-18T17:06:55Z","updated_at":"2016-11-18T17:06:55Z","html_url":"https://github.com/elastic/elasticsearch/pull/21630#discussion_r88696797","pull_request_url":"https://api.github.com/repos/elastic/elasticsearch/pulls/21630","_links":{"self":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/comments/88696797"},"html":{"href":"https://github.com/elastic/elasticsearch/pull/21630#discussion_r88696797"},"pull_request":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/21630"}}},"pull_request":{"url":"https://api.github.com/repos/elastic/elasticsearch/pulls/21630","id":94212094,"html_url":"https://github.com/elastic/elasticsearch/pull/21630","diff_url":"https://github.com/elastic/elasticsearch/pull/21630.diff","patch_url":"https://github.com/elastic/elasticsearch/pull/21630.patch","issue_url":"https://api.github.com/repos/elastic/elasticsearch/issues/21630","number":21630,"state":"open","locked":false,"title":"Lazy resolve unicast hosts","user":{"login":"jasontedor","id":4744941,"avatar_url":"https://avatars.githubusercontent.com/u/4744941?v=3","gravatar_id":"","url":"https://api.github.com/users/jasontedor","html_url":"https://github.com/jasontedor","followers_url":"https://api.github.com/users/jasontedor/followers","following_url":"https://api.github.com/users/jasontedor/following{/other_user}","gists_url":"https://api.github.com/users/jasontedor/gists{/gist_id}","starred_url":"https://api.github.com/users/jasontedor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jasontedor/subscriptions","organizations_url":"https://api.github.com/users/jasontedor/orgs","repos_url":"https://api.github.com/users/jasontedor/repos","events_url":"https://api.github.com/users/jasontedor/events{/privacy}","received_events_url":"https://api.github.com/users/jasontedor/received_events","type":"User","site_admin":false},"body":"Today we eagerly resolve unicast hosts. This means that if DNS changes,\r\nwe will never find the host at the new address. Moreover, a single host\r\nfailng to resolve causes startup to abort. This commit introduces lazy\r\nresolution of unicast hosts. If a DNS entry changes, there is an\r\nopportunity for the host to be discovered. Note that under the Java\r\nsecurity manager, there is a default positive cache of infinity for\r\nresolved hosts; this means that if a user does want to operate in an\r\nenvironment where DNS can change, they must adjust\r\nnetworkaddress.cache.ttl in their security policy. And if a host fails\r\nto resolve, we warn log the hostname but continue pinging other\r\nconfigured hosts.\r\n\r\nWhen doing DNS resolutions for unicast hostnames, we wait until the DNS\r\nlookups timeout. This appears to be forty-five seconds on modern JVMs,\r\nand it is not configurable. If we do these serially, the cluster can be\r\nblocked during ping for a lengthy period of time. This commit introduces\r\ndoing the DNS lookups in parallel on the generic thread pool, and adds a\r\nuser-configurable timeout for these lookups.\r\n\r\nCloses #14441, closes #16412\r\n","created_at":"2016-11-17T17:22:58Z","updated_at":"2016-11-18T17:06:55Z","closed_at":null,"merged_at":null,"merge_commit_sha":"56446044f213565faaa9412b618c7c7a356184f8","assignee":{"login":"s1monw","id":973334,"avatar_url":"https://avatars.githubusercontent.com/u/973334?v=3","gravatar_id":"","url":"https://api.github.com/users/s1monw","html_url":"https://github.com/s1monw","followers_url":"https://api.github.com/users/s1monw/followers","following_url":"https://api.github.com/users/s1monw/following{/other_user}","gists_url":"https://api.github.com/users/s1monw/gists{/gist_id}","starred_url":"https://api.github.com/users/s1monw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/s1monw/subscriptions","organizations_url":"https://api.github.com/users/s1monw/orgs","repos_url":"https://api.github.com/users/s1monw/repos","events_url":"https://api.github.com/users/s1monw/events{/privacy}","received_events_url":"https://api.github.com/users/s1monw/received_events","type":"User","site_admin":false},"assignees":[{"login":"s1monw","id":973334,"avatar_url":"https://avatars.githubusercontent.com/u/973334?v=3","gravatar_id":"","url":"https://api.github.com/users/s1monw","html_url":"https://github.com/s1monw","followers_url":"https://api.github.com/users/s1monw/followers","following_url":"https://api.github.com/users/s1monw/following{/other_user}","gists_url":"https://api.github.com/users/s1monw/gists{/gist_id}","starred_url":"https://api.github.com/users/s1monw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/s1monw/subscriptions","organizations_url":"https://api.github.com/users/s1monw/orgs","repos_url":"https://api.github.com/users/s1monw/repos","events_url":"https://api.github.com/users/s1monw/events{/privacy}","received_events_url":"https://api.github.com/users/s1monw/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/elastic/elasticsearch/pulls/21630/commits","review_comments_url":"https://api.github.com/repos/elastic/elasticsearch/pulls/21630/comments","review_comment_url":"https://api.github.com/repos/elastic/elasticsearch/pulls/comments{/number}","comments_url":"https://api.github.com/repos/elastic/elasticsearch/issues/21630/comments","statuses_url":"https://api.github.com/repos/elastic/elasticsearch/statuses/4868321727293ea3edf11dd6b3aabe6b3d75387c","head":{"label":"jasontedor:lazy-resolve","ref":"lazy-resolve","sha":"4868321727293ea3edf11dd6b3aabe6b3d75387c","user":{"login":"jasontedor","id":4744941,"avatar_url":"https://avatars.githubusercontent.com/u/4744941?v=3","gravatar_id":"","url":"https://api.github.com/users/jasontedor","html_url":"https://github.com/jasontedor","followers_url":"https://api.github.com/users/jasontedor/followers","following_url":"https://api.github.com/users/jasontedor/following{/other_user}","gists_url":"https://api.github.com/users/jasontedor/gists{/gist_id}","starred_url":"https://api.github.com/users/jasontedor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jasontedor/subscriptions","organizations_url":"https://api.github.com/users/jasontedor/orgs","repos_url":"https://api.github.com/users/jasontedor/repos","events_url":"https://api.github.com/users/jasontedor/events{/privacy}","received_events_url":"https://api.github.com/users/jasontedor/received_events","type":"User","site_admin":false},"repo":{"id":71962406,"name":"elasticsearch","full_name":"jasontedor/elasticsearch","owner":{"login":"jasontedor","id":4744941,"avatar_url":"https://avatars.githubusercontent.com/u/4744941?v=3","gravatar_id":"","url":"https://api.github.com/users/jasontedor","html_url":"https://github.com/jasontedor","followers_url":"https://api.github.com/users/jasontedor/followers","following_url":"https://api.github.com/users/jasontedor/following{/other_user}","gists_url":"https://api.github.com/users/jasontedor/gists{/gist_id}","starred_url":"https://api.github.com/users/jasontedor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jasontedor/subscriptions","organizations_url":"https://api.github.com/users/jasontedor/orgs","repos_url":"https://api.github.com/users/jasontedor/repos","events_url":"https://api.github.com/users/jasontedor/events{/privacy}","received_events_url":"https://api.github.com/users/jasontedor/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jasontedor/elasticsearch","description":"Open Source, Distributed, RESTful Search Engine","fork":true,"url":"https://api.github.com/repos/jasontedor/elasticsearch","forks_url":"https://api.github.com/repos/jasontedor/elasticsearch/forks","keys_url":"https://api.github.com/repos/jasontedor/elasticsearch/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jasontedor/elasticsearch/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jasontedor/elasticsearch/teams","hooks_url":"https://api.github.com/repos/jasontedor/elasticsearch/hooks","issue_events_url":"https://api.github.com/repos/jasontedor/elasticsearch/issues/events{/number}","events_url":"https://api.github.com/repos/jasontedor/elasticsearch/events","assignees_url":"https://api.github.com/repos/jasontedor/elasticsearch/assignees{/user}","branches_url":"https://api.github.com/repos/jasontedor/elasticsearch/branches{/branch}","tags_url":"https://api.github.com/repos/jasontedor/elasticsearch/tags","blobs_url":"https://api.github.com/repos/jasontedor/elasticsearch/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jasontedor/elasticsearch/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jasontedor/elasticsearch/git/refs{/sha}","trees_url":"https://api.github.com/repos/jasontedor/elasticsearch/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jasontedor/elasticsearch/statuses/{sha}","languages_url":"https://api.github.com/repos/jasontedor/elasticsearch/languages","stargazers_url":"https://api.github.com/repos/jasontedor/elasticsearch/stargazers","contributors_url":"https://api.github.com/repos/jasontedor/elasticsearch/contributors","subscribers_url":"https://api.github.com/repos/jasontedor/elasticsearch/subscribers","subscription_url":"https://api.github.com/repos/jasontedor/elasticsearch/subscription","commits_url":"https://api.github.com/repos/jasontedor/elasticsearch/commits{/sha}","git_commits_url":"https://api.github.com/repos/jasontedor/elasticsearch/git/commits{/sha}","comments_url":"https://api.github.com/repos/jasontedor/elasticsearch/comments{/number}","issue_comment_url":"https://api.github.com/repos/jasontedor/elasticsearch/issues/comments{/number}","contents_url":"https://api.github.com/repos/jasontedor/elasticsearch/contents/{+path}","compare_url":"https://api.github.com/repos/jasontedor/elasticsearch/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jasontedor/elasticsearch/merges","archive_url":"https://api.github.com/repos/jasontedor/elasticsearch/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jasontedor/elasticsearch/downloads","issues_url":"https://api.github.com/repos/jasontedor/elasticsearch/issues{/number}","pulls_url":"https://api.github.com/repos/jasontedor/elasticsearch/pulls{/number}","milestones_url":"https://api.github.com/repos/jasontedor/elasticsearch/milestones{/number}","notifications_url":"https://api.github.com/repos/jasontedor/elasticsearch/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jasontedor/elasticsearch/labels{/name}","releases_url":"https://api.github.com/repos/jasontedor/elasticsearch/releases{/id}","deployments_url":"https://api.github.com/repos/jasontedor/elasticsearch/deployments","created_at":"2016-10-26T03:23:35Z","updated_at":"2016-10-26T03:24:01Z","pushed_at":"2016-11-18T12:06:11Z","git_url":"git://github.com/jasontedor/elasticsearch.git","ssh_url":"git@github.com:jasontedor/elasticsearch.git","clone_url":"https://github.com/jasontedor/elasticsearch.git","svn_url":"https://github.com/jasontedor/elasticsearch","homepage":"https://www.elastic.co/products/elasticsearch","size":260469,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"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":"elastic:master","ref":"master","sha":"4a7b70cc082953dc7cd09b715916e3d1f8813f74","user":{"login":"elastic","id":6764390,"avatar_url":"https://avatars.githubusercontent.com/u/6764390?v=3","gravatar_id":"","url":"https://api.github.com/users/elastic","html_url":"https://github.com/elastic","followers_url":"https://api.github.com/users/elastic/followers","following_url":"https://api.github.com/users/elastic/following{/other_user}","gists_url":"https://api.github.com/users/elastic/gists{/gist_id}","starred_url":"https://api.github.com/users/elastic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elastic/subscriptions","organizations_url":"https://api.github.com/users/elastic/orgs","repos_url":"https://api.github.com/users/elastic/repos","events_url":"https://api.github.com/users/elastic/events{/privacy}","received_events_url":"https://api.github.com/users/elastic/received_events","type":"Organization","site_admin":false},"repo":{"id":507775,"name":"elasticsearch","full_name":"elastic/elasticsearch","owner":{"login":"elastic","id":6764390,"avatar_url":"https://avatars.githubusercontent.com/u/6764390?v=3","gravatar_id":"","url":"https://api.github.com/users/elastic","html_url":"https://github.com/elastic","followers_url":"https://api.github.com/users/elastic/followers","following_url":"https://api.github.com/users/elastic/following{/other_user}","gists_url":"https://api.github.com/users/elastic/gists{/gist_id}","starred_url":"https://api.github.com/users/elastic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elastic/subscriptions","organizations_url":"https://api.github.com/users/elastic/orgs","repos_url":"https://api.github.com/users/elastic/repos","events_url":"https://api.github.com/users/elastic/events{/privacy}","received_events_url":"https://api.github.com/users/elastic/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/elastic/elasticsearch","description":"Open Source, Distributed, RESTful Search Engine","fork":false,"url":"https://api.github.com/repos/elastic/elasticsearch","forks_url":"https://api.github.com/repos/elastic/elasticsearch/forks","keys_url":"https://api.github.com/repos/elastic/elasticsearch/keys{/key_id}","collaborators_url":"https://api.github.com/repos/elastic/elasticsearch/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/elastic/elasticsearch/teams","hooks_url":"https://api.github.com/repos/elastic/elasticsearch/hooks","issue_events_url":"https://api.github.com/repos/elastic/elasticsearch/issues/events{/number}","events_url":"https://api.github.com/repos/elastic/elasticsearch/events","assignees_url":"https://api.github.com/repos/elastic/elasticsearch/assignees{/user}","branches_url":"https://api.github.com/repos/elastic/elasticsearch/branches{/branch}","tags_url":"https://api.github.com/repos/elastic/elasticsearch/tags","blobs_url":"https://api.github.com/repos/elastic/elasticsearch/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/elastic/elasticsearch/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/elastic/elasticsearch/git/refs{/sha}","trees_url":"https://api.github.com/repos/elastic/elasticsearch/git/trees{/sha}","statuses_url":"https://api.github.com/repos/elastic/elasticsearch/statuses/{sha}","languages_url":"https://api.github.com/repos/elastic/elasticsearch/languages","stargazers_url":"https://api.github.com/repos/elastic/elasticsearch/stargazers","contributors_url":"https://api.github.com/repos/elastic/elasticsearch/contributors","subscribers_url":"https://api.github.com/repos/elastic/elasticsearch/subscribers","subscription_url":"https://api.github.com/repos/elastic/elasticsearch/subscription","commits_url":"https://api.github.com/repos/elastic/elasticsearch/commits{/sha}","git_commits_url":"https://api.github.com/repos/elastic/elasticsearch/git/commits{/sha}","comments_url":"https://api.github.com/repos/elastic/elasticsearch/comments{/number}","issue_comment_url":"https://api.github.com/repos/elastic/elasticsearch/issues/comments{/number}","contents_url":"https://api.github.com/repos/elastic/elasticsearch/contents/{+path}","compare_url":"https://api.github.com/repos/elastic/elasticsearch/compare/{base}...{head}","merges_url":"https://api.github.com/repos/elastic/elasticsearch/merges","archive_url":"https://api.github.com/repos/elastic/elasticsearch/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/elastic/elasticsearch/downloads","issues_url":"https://api.github.com/repos/elastic/elasticsearch/issues{/number}","pulls_url":"https://api.github.com/repos/elastic/elasticsearch/pulls{/number}","milestones_url":"https://api.github.com/repos/elastic/elasticsearch/milestones{/number}","notifications_url":"https://api.github.com/repos/elastic/elasticsearch/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/elastic/elasticsearch/labels{/name}","releases_url":"https://api.github.com/repos/elastic/elasticsearch/releases{/id}","deployments_url":"https://api.github.com/repos/elastic/elasticsearch/deployments","created_at":"2010-02-08T13:20:56Z","updated_at":"2016-11-18T15:21:50Z","pushed_at":"2016-11-18T16:48:17Z","git_url":"git://github.com/elastic/elasticsearch.git","ssh_url":"git@github.com:elastic/elasticsearch.git","clone_url":"https://github.com/elastic/elasticsearch.git","svn_url":"https://github.com/elastic/elasticsearch","homepage":"https://www.elastic.co/products/elasticsearch","size":375575,"stargazers_count":19397,"watchers_count":19397,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":6644,"mirror_url":null,"open_issues_count":1196,"forks":6644,"open_issues":1196,"watchers":19397,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/21630"},"html":{"href":"https://github.com/elastic/elasticsearch/pull/21630"},"issue":{"href":"https://api.github.com/repos/elastic/elasticsearch/issues/21630"},"comments":{"href":"https://api.github.com/repos/elastic/elasticsearch/issues/21630/comments"},"review_comments":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/21630/comments"},"review_comment":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/21630/commits"},"statuses":{"href":"https://api.github.com/repos/elastic/elasticsearch/statuses/4868321727293ea3edf11dd6b3aabe6b3d75387c"}}}}
{"actor":{"display_login":"rjernst"}}