{"action":"created","comment":{"url":"https://api.github.com/repos/hazelcast/hazelcast/pulls/comments/219056898","pull_request_review_id":157134558,"id":219056898,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIxOTA1Njg5OA==","diff_hunk":"@@ -0,0 +1,222 @@\n+package com.hazelcast.internal.probing;\n+\n+import com.hazelcast.internal.metrics.Probe;\n+import com.hazelcast.internal.metrics.ProbeLevel;\n+import com.hazelcast.internal.probing.ProbeRegistry.ProbeSource;\n+import com.hazelcast.spi.annotation.Beta;\n+import com.hazelcast.spi.annotation.PrivateApi;\n+\n+/**\n+ * For each probe measurement a {@link ProbingCycle} is passed to all\n+ * {@link ProbeSource}s. The {@link ProbeSource} uses the API to communicate its\n+ * probes and their current values. \n+ * \n+ * This has two steps:\n+ * <ol>\n+ * <li>{@link #openContext()} and {@link Tags#tag(CharSequence, CharSequence)}\n+ * is used to describe the general context of the probes. The context described\n+ * before acts as a \"prefix\" for all subsequent measurements.</li>\n+ * \n+ * <li>{@link #probe(CharSequence, long)} and its sibling methods are used to\n+ * state one measurement at a time with its name and value. Alternatively to\n+ * stating measurements directly an instance of a type annotated with\n+ * {@link Probe} can be passed to {@link #probe(Object)} to measure all\n+ * annotated fields and methods.</li>\n+ * </ol>\n+ * \n+ * Some sources might describe several of such contexts and their probes by\n+ * repeating the two steps:\n+ * \n+ * <pre>\n+ * public void probeIn(ProbingCycle cycle) {\n+ *     cycle.openContext().tag(TAG_TYPE, \"x\").tag(TAG_INSTANCE, \"foo\");\n+ *     cycle.probe(foo);\n+ *     cycle.openContext().tag(TAG_INSTANCE, \"bar\");\n+ *     cycle.probe(bar);\n+ * }\n+ * </pre>\n+ */\n+@Beta\n+@PrivateApi\n+public interface ProbingCycle {\n+\n+    /*\n+     * Probing values:\n+     */\n+\n+    /**\n+     * Allows {@link ProbeSource}s to optimize their implementations by skipping\n+     * handling probes for {@link ProbeLevel}s that are not relevant.\n+     * \n+     * {@link ProbeSource}s do not have to obligation to perform this check. They\n+     * may just probe everything providing the level for each probe. It is the\n+     * {@link ProbingCycle}s obligation to make sure only relevant probes are\n+     * considered.\n+     * \n+     * @param level the level to check\n+     * @return true, if the level is relevant for this cycle, else false\n+     */\n+    boolean isProbed(ProbeLevel level);\n+\n+    /**\n+     * The main way of rendering metrics is to render instances that have methods\n+     * and fields annotated with {@link Probe}. The metric name is derived from\n+     * field or method name or {@link Probe#name()} (if given). The metric type\n+     * (long or double) is derived from the field type or method return type. The\n+     * set of supported types with a known mapping is fix and implementation\n+     * dependent.\n+     * \n+     * The method exits with the same {@link Tags} context it is called with.\n+     * \n+     * @param instance a obj with fields or methods annotated with {@link Probe}\n+     */\n+    void probe(Object instance);\n+\n+    /**\n+     * Default method to call {@link #probe(Object)} for an array of instances. This\n+     * is mostly useful for types that implement {@link Tagging} and thereby provide\n+     * their own context.\n+     * \n+     * The method exits with the same {@link Tags} context it is called with.\n+     * Instances do not affect each others context.\n+     * \n+     * @param instances may be null (no effect)\n+     */\n+    void probe(Object[] instances);\n+\n+    /**\n+     * Similar to {@link #probe(Object)} just that all names become\n+     * {@code <prefix>.<name>} instead of just {@code <name>}.\n+     * \n+     * The method exits with the same {@link Tags} context it is called with.\n+     * \n+     * @param prefix prefix to use for all names (provided without dot)\n+     * @param instance a obj with fields or methods annotated with {@link Probe}\n+     */\n+    void probe(CharSequence prefix, Object instance);\n+\n+    /**\n+     * Similar to {@link #probe(Object)} just that probed methods are not identified\n+     * using annotations but given as a list. All methods use the specified level.\n+     * No fields will be probed.\n+     * \n+     * This can be used to probe beans that cannot be annotated. To prefix this\n+     * {@link Tags#prefix(CharSequence)} can be used. Remember though that the\n+     * prefix will remain in the context.\n+     * \n+     * @param level the level to use for all probes created\n+     * @param instance the obj whose methods to probe.\n+     * @param methods the names of the methods to probe. Methods that do not exist\n+     *        or have the wrong number of arguments (not none) are ignored.\n+     */\n+    void probe(ProbeLevel level, Object instance, String... methods);\n+\n+    void probe(CharSequence name, long value);\n+\n+    void probe(CharSequence name, double value);\n+\n+    void probe(CharSequence name, boolean value);\n+\n+    void probe(ProbeLevel level, CharSequence name, long value);\n+\n+    void probe(ProbeLevel level, CharSequence name, double value);\n+\n+    void probe(ProbeLevel level, CharSequence name, boolean value);\n+\n+    /**\n+     * Used to forward metrics received from the client. This is only different from\n+     * {@link #probe(CharSequence, long)} except that it will not escape the name\n+     * but un-escaping escaped backslashes.\n+     * \n+     * @param name a properly escaped name (as written before)\n+     * @param value value as written before (double already converted to long)\n+     */\n+    void probeForwarded(CharSequence name, long value);\n+\n+    /*\n+     * Describing probing context to the cycle:\n+     */\n+\n+    /**\n+     * Resets the tags used by this cycle (to empty). This provides a convenient and\n+     * format independent way of tagging the probed metrics.\n+     * \n+     * After context (previously the prefix) is completed using\n+     * {@link Tags#tag(CharSequence, CharSequence)} the {@code probe} methods are\n+     * used to add measurements in this context. Then context is changed to next one\n+     * and so forth.\n+     * \n+     * @return the {@link Tags} abstraction to use to build the context for this\n+     *         cycle.\n+     */\n+    Tags openContext();\n+\n+    /**\n+     * The reason for {@link Tags} API is to allow \"describing\" complex \"assembled\"\n+     * multi-part keys to the {@link ProbingCycle} without the need to create\n+     * intermediate objects like {@link String} concatenation would.\n+     */\n+    interface Tags {\n+\n+        /**\n+         * Append the tag to the context. If the name is identical to the last name the\n+         * pair is not appended but the value just changes to the new value provided.\n+         * This allows to setup tags that are identical for a collection first and just\n+         * switch the varying tag to the current value in the loop. This does not work\n+         * with more then one tag. In such cases the context has to be opened and\n+         * reconstructed for each loop iteration.\n+         * \n+         * The given {@link CharSequence} for {@code value} will always be escaped.\n+         * \n+         * @param name not null, only guaranteed to be stable throughout the call\n+         * @param value not null, only guaranteed to be stable throughout the call\n+         * @return this {@link Tags} context for chaining\n+         */\n+        Tags tag(CharSequence name, CharSequence value);\n+\n+        /**\n+         * This method is meat as a legacy support where keys are not build in terms of tags.\n+         * It should only be used in exceptional cases. At some point we hopefully can remove it.\n+         * \n+         * The given {@link CharSequence} will always be escaped.\n+         * \n+         * @param s not null, only guaranteed to be stable throughout the call\n+         * @return this {@link Tags} context for chaining\n+         */\n+        Tags append(CharSequence s);\n+\n+        /**\n+         * Same as {@link #append(CharSequence)} + {@code append(\".\")} unless the prefix\n+         * is empty in which case nothing is appended.\n+         * \n+         * The given {@link CharSequence} will always be escaped.\n+         * \n+         * @param prefix not null, only guaranteed to be stable throughout the call\n+         * @return this {@link Tags} context for chaining\n+         */\n+        Tags prefix(CharSequence prefix);\n+    }\n+\n+    /**\n+     * Can be implemented by instances passed to {@link ProbingCycle#probe(Object)}\n+     * (and its sibling methods) to provided the {@link Tags} context by the object\n+     * itself instead of before calling {@code probe}.\n+     */\n+    interface Tagging {","path":"hazelcast/src/main/java/com/hazelcast/internal/probing/ProbingCycle.java","position":205,"original_position":205,"commit_id":"8e043d703b56e8433f28be31a0d9c2f707c81ffd","original_commit_id":"8e043d703b56e8433f28be31a0d9c2f707c81ffd","user":{"login":"pveentjer","id":105243,"node_id":"MDQ6VXNlcjEwNTI0Mw==","avatar_url":"https://avatars2.githubusercontent.com/u/105243?v=4","gravatar_id":"","url":"https://api.github.com/users/pveentjer","html_url":"https://github.com/pveentjer","followers_url":"https://api.github.com/users/pveentjer/followers","following_url":"https://api.github.com/users/pveentjer/following{/other_user}","gists_url":"https://api.github.com/users/pveentjer/gists{/gist_id}","starred_url":"https://api.github.com/users/pveentjer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pveentjer/subscriptions","organizations_url":"https://api.github.com/users/pveentjer/orgs","repos_url":"https://api.github.com/users/pveentjer/repos","events_url":"https://api.github.com/users/pveentjer/events{/privacy}","received_events_url":"https://api.github.com/users/pveentjer/received_events","type":"User","site_admin":false},"body":"inner interface. Please pull it into top level.","created_at":"2018-09-20T07:14:08Z","updated_at":"2018-09-20T07:14:09Z","html_url":"https://github.com/hazelcast/hazelcast/pull/13806#discussion_r219056898","pull_request_url":"https://api.github.com/repos/hazelcast/hazelcast/pulls/13806","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/hazelcast/hazelcast/pulls/comments/219056898"},"html":{"href":"https://github.com/hazelcast/hazelcast/pull/13806#discussion_r219056898"},"pull_request":{"href":"https://api.github.com/repos/hazelcast/hazelcast/pulls/13806"}}},"pull_request":{"url":"https://api.github.com/repos/hazelcast/hazelcast/pulls/13806","id":216690555,"node_id":"MDExOlB1bGxSZXF1ZXN0MjE2NjkwNTU1","html_url":"https://github.com/hazelcast/hazelcast/pull/13806","diff_url":"https://github.com/hazelcast/hazelcast/pull/13806.diff","patch_url":"https://github.com/hazelcast/hazelcast/pull/13806.patch","issue_url":"https://api.github.com/repos/hazelcast/hazelcast/issues/13806","number":13806,"state":"open","locked":false,"title":"[3.12] Flexible low impact metrics probing","user":{"login":"jbee","id":309438,"node_id":"MDQ6VXNlcjMwOTQzOA==","avatar_url":"https://avatars3.githubusercontent.com/u/309438?v=4","gravatar_id":"","url":"https://api.github.com/users/jbee","html_url":"https://github.com/jbee","followers_url":"https://api.github.com/users/jbee/followers","following_url":"https://api.github.com/users/jbee/following{/other_user}","gists_url":"https://api.github.com/users/jbee/gists{/gist_id}","starred_url":"https://api.github.com/users/jbee/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jbee/subscriptions","organizations_url":"https://api.github.com/users/jbee/orgs","repos_url":"https://api.github.com/users/jbee/repos","events_url":"https://api.github.com/users/jbee/events{/privacy}","received_events_url":"https://api.github.com/users/jbee/received_events","type":"User","site_admin":false},"body":"Main goal was to provide a low memory consumption, low garbage probing in IMDG that also addresses the needs for a more flexible, low cost (additions and maintenance) metrics system for MC.\r\n\r\nIn the center of the change we go from `MetricsRegistry` to `ProbeRegistry`.\r\n\r\n**Starting Situation** \r\nThe old model was centered around a list of \"known\" probes that were registered on initialization. Dynamically changing probes (in presence or number) had to be managed by adding and removing them in connection with suiting events.\r\n\r\nConsequences: \r\n1. the memory needed grew linear with the number of probes\r\n2. dynamic probes required dedicated code and discipline to keep list of probes in sync with reality\r\n3. creation of garbage objects during registration was less relevant as only occurring once\r\n4. adding dynamic probes was costly (time/money/complexity) \r\n5. probes were predictable and could be globally ordered or probed individually\r\n\r\nWith an expected increase in number of probes due to MC using them as its main data source the memory consumption and the costs raised concerns about the model and its performance.\r\n\r\n**Solution**\r\nThe new model is centered around a list of \"known\" probe **sources** that are registered on initialization. The number of sources is small and fixed. The actual probes are \"discovered\" during each rendering cycle by asking the known sources to \"publish\" their probes or probe data. The API is design so that rendering probe data can be done in a way that avoids creating intermediate objects that become garbage. \r\n\r\nConsequences:\r\n1. memory consumption is low and fixed\r\n2. dynamic probes do not require special treatment (no dedicated code or state management)\r\n3. avoiding the creation of garbage objects during probing is highly relevant as occurring regularly\r\n4. adding dynamic probes is as cheap as adding fixed ones\r\n5. probes are not predictable and can only be ordered within local groups but not probed individually\r\n\r\n**Main Sources of Garbage**\r\nProbing is mostly garbage free. Some garbage cannot be avoided:\r\n* Iterator objects when iterating collections or maps\r\n* Primitive wrappers when probing methods returning primitives via reflection\r\n\r\n**Semantic Changes**\r\n* Clients collect and render the client statistics using the `ProbeRegistry`. As a consequence the `ProbeLevel` will now be obeyed. The client statistics no longer consist of a fix map of metrics but are dynamic and contain all metrics collected on client.\r\n* The client statistics send as `String` to a member is now split into the individual metrics by the member (without creating additional garbage) instead of sending it to MC and have MC deal with the `String`. \r\n* `HealthMonitor` runs a reduced set of `ProbeSource`s in `ProbeLevel.MANDATORY` to collect roughly the data it is interested in. Required probes not already being `MANDATORY` where made `MANDATORY` for that purpose.\r\n* Probing at different `ProbeLevel`s is possible (level are now dynamic)\r\n* `LocalXyzStats` classes now cache whether or not statistics for the object was enabled\r\n* only objects with enabled statistics are probed\r\n\r\nTo be continued...","created_at":"2018-09-19T15:52:20Z","updated_at":"2018-09-20T07:14:09Z","closed_at":null,"merged_at":null,"merge_commit_sha":"db17e9265ca6ea93718e881c5ad19d0ce3d973cd","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":137752575,"node_id":"MDU6TGFiZWwxMzc3NTI1NzU=","url":"https://api.github.com/repos/hazelcast/hazelcast/labels/Team:%20Core","name":"Team: Core","color":"fef2c0","default":false},{"id":1740692,"node_id":"MDU6TGFiZWwxNzQwNjky","url":"https://api.github.com/repos/hazelcast/hazelcast/labels/Type:%20Enhancement","name":"Type: Enhancement","color":"5319e7","default":false}],"milestone":{"url":"https://api.github.com/repos/hazelcast/hazelcast/milestones/112","html_url":"https://github.com/hazelcast/hazelcast/milestone/112","labels_url":"https://api.github.com/repos/hazelcast/hazelcast/milestones/112/labels","id":3354840,"node_id":"MDk6TWlsZXN0b25lMzM1NDg0MA==","number":112,"title":"3.12","description":null,"creator":{"login":"burakcelebi","id":928875,"node_id":"MDQ6VXNlcjkyODg3NQ==","avatar_url":"https://avatars1.githubusercontent.com/u/928875?v=4","gravatar_id":"","url":"https://api.github.com/users/burakcelebi","html_url":"https://github.com/burakcelebi","followers_url":"https://api.github.com/users/burakcelebi/followers","following_url":"https://api.github.com/users/burakcelebi/following{/other_user}","gists_url":"https://api.github.com/users/burakcelebi/gists{/gist_id}","starred_url":"https://api.github.com/users/burakcelebi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/burakcelebi/subscriptions","organizations_url":"https://api.github.com/users/burakcelebi/orgs","repos_url":"https://api.github.com/users/burakcelebi/repos","events_url":"https://api.github.com/users/burakcelebi/events{/privacy}","received_events_url":"https://api.github.com/users/burakcelebi/received_events","type":"User","site_admin":false},"open_issues":237,"closed_issues":5,"state":"open","created_at":"2018-05-17T14:36:02Z","updated_at":"2018-09-19T15:58:01Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/hazelcast/hazelcast/pulls/13806/commits","review_comments_url":"https://api.github.com/repos/hazelcast/hazelcast/pulls/13806/comments","review_comment_url":"https://api.github.com/repos/hazelcast/hazelcast/pulls/comments{/number}","comments_url":"https://api.github.com/repos/hazelcast/hazelcast/issues/13806/comments","statuses_url":"https://api.github.com/repos/hazelcast/hazelcast/statuses/8e043d703b56e8433f28be31a0d9c2f707c81ffd","head":{"label":"jbee:sktech-probe-rendering","ref":"sktech-probe-rendering","sha":"8e043d703b56e8433f28be31a0d9c2f707c81ffd","user":{"login":"jbee","id":309438,"node_id":"MDQ6VXNlcjMwOTQzOA==","avatar_url":"https://avatars3.githubusercontent.com/u/309438?v=4","gravatar_id":"","url":"https://api.github.com/users/jbee","html_url":"https://github.com/jbee","followers_url":"https://api.github.com/users/jbee/followers","following_url":"https://api.github.com/users/jbee/following{/other_user}","gists_url":"https://api.github.com/users/jbee/gists{/gist_id}","starred_url":"https://api.github.com/users/jbee/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jbee/subscriptions","organizations_url":"https://api.github.com/users/jbee/orgs","repos_url":"https://api.github.com/users/jbee/repos","events_url":"https://api.github.com/users/jbee/events{/privacy}","received_events_url":"https://api.github.com/users/jbee/received_events","type":"User","site_admin":false},"repo":{"id":118611399,"node_id":"MDEwOlJlcG9zaXRvcnkxMTg2MTEzOTk=","name":"hazelcast","full_name":"jbee/hazelcast","private":false,"owner":{"login":"jbee","id":309438,"node_id":"MDQ6VXNlcjMwOTQzOA==","avatar_url":"https://avatars3.githubusercontent.com/u/309438?v=4","gravatar_id":"","url":"https://api.github.com/users/jbee","html_url":"https://github.com/jbee","followers_url":"https://api.github.com/users/jbee/followers","following_url":"https://api.github.com/users/jbee/following{/other_user}","gists_url":"https://api.github.com/users/jbee/gists{/gist_id}","starred_url":"https://api.github.com/users/jbee/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jbee/subscriptions","organizations_url":"https://api.github.com/users/jbee/orgs","repos_url":"https://api.github.com/users/jbee/repos","events_url":"https://api.github.com/users/jbee/events{/privacy}","received_events_url":"https://api.github.com/users/jbee/received_events","type":"User","site_admin":false},"html_url":"https://github.com/jbee/hazelcast","description":"Open Source In-Memory Data Grid","fork":true,"url":"https://api.github.com/repos/jbee/hazelcast","forks_url":"https://api.github.com/repos/jbee/hazelcast/forks","keys_url":"https://api.github.com/repos/jbee/hazelcast/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jbee/hazelcast/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jbee/hazelcast/teams","hooks_url":"https://api.github.com/repos/jbee/hazelcast/hooks","issue_events_url":"https://api.github.com/repos/jbee/hazelcast/issues/events{/number}","events_url":"https://api.github.com/repos/jbee/hazelcast/events","assignees_url":"https://api.github.com/repos/jbee/hazelcast/assignees{/user}","branches_url":"https://api.github.com/repos/jbee/hazelcast/branches{/branch}","tags_url":"https://api.github.com/repos/jbee/hazelcast/tags","blobs_url":"https://api.github.com/repos/jbee/hazelcast/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jbee/hazelcast/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jbee/hazelcast/git/refs{/sha}","trees_url":"https://api.github.com/repos/jbee/hazelcast/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jbee/hazelcast/statuses/{sha}","languages_url":"https://api.github.com/repos/jbee/hazelcast/languages","stargazers_url":"https://api.github.com/repos/jbee/hazelcast/stargazers","contributors_url":"https://api.github.com/repos/jbee/hazelcast/contributors","subscribers_url":"https://api.github.com/repos/jbee/hazelcast/subscribers","subscription_url":"https://api.github.com/repos/jbee/hazelcast/subscription","commits_url":"https://api.github.com/repos/jbee/hazelcast/commits{/sha}","git_commits_url":"https://api.github.com/repos/jbee/hazelcast/git/commits{/sha}","comments_url":"https://api.github.com/repos/jbee/hazelcast/comments{/number}","issue_comment_url":"https://api.github.com/repos/jbee/hazelcast/issues/comments{/number}","contents_url":"https://api.github.com/repos/jbee/hazelcast/contents/{+path}","compare_url":"https://api.github.com/repos/jbee/hazelcast/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jbee/hazelcast/merges","archive_url":"https://api.github.com/repos/jbee/hazelcast/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jbee/hazelcast/downloads","issues_url":"https://api.github.com/repos/jbee/hazelcast/issues{/number}","pulls_url":"https://api.github.com/repos/jbee/hazelcast/pulls{/number}","milestones_url":"https://api.github.com/repos/jbee/hazelcast/milestones{/number}","notifications_url":"https://api.github.com/repos/jbee/hazelcast/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jbee/hazelcast/labels{/name}","releases_url":"https://api.github.com/repos/jbee/hazelcast/releases{/id}","deployments_url":"https://api.github.com/repos/jbee/hazelcast/deployments","created_at":"2018-01-23T13:06:06Z","updated_at":"2018-09-19T15:17:56Z","pushed_at":"2018-09-19T15:27:01Z","git_url":"git://github.com/jbee/hazelcast.git","ssh_url":"git@github.com:jbee/hazelcast.git","clone_url":"https://github.com/jbee/hazelcast.git","svn_url":"https://github.com/jbee/hazelcast","homepage":"http://www.hazelcast.org","size":134823,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"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":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"hazelcast:master","ref":"master","sha":"20293d173f1f09e3f4a93fd292a8a288a2e676a9","user":{"login":"hazelcast","id":1453152,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE0NTMxNTI=","avatar_url":"https://avatars2.githubusercontent.com/u/1453152?v=4","gravatar_id":"","url":"https://api.github.com/users/hazelcast","html_url":"https://github.com/hazelcast","followers_url":"https://api.github.com/users/hazelcast/followers","following_url":"https://api.github.com/users/hazelcast/following{/other_user}","gists_url":"https://api.github.com/users/hazelcast/gists{/gist_id}","starred_url":"https://api.github.com/users/hazelcast/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hazelcast/subscriptions","organizations_url":"https://api.github.com/users/hazelcast/orgs","repos_url":"https://api.github.com/users/hazelcast/repos","events_url":"https://api.github.com/users/hazelcast/events{/privacy}","received_events_url":"https://api.github.com/users/hazelcast/received_events","type":"Organization","site_admin":false},"repo":{"id":3786237,"node_id":"MDEwOlJlcG9zaXRvcnkzNzg2MjM3","name":"hazelcast","full_name":"hazelcast/hazelcast","private":false,"owner":{"login":"hazelcast","id":1453152,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE0NTMxNTI=","avatar_url":"https://avatars2.githubusercontent.com/u/1453152?v=4","gravatar_id":"","url":"https://api.github.com/users/hazelcast","html_url":"https://github.com/hazelcast","followers_url":"https://api.github.com/users/hazelcast/followers","following_url":"https://api.github.com/users/hazelcast/following{/other_user}","gists_url":"https://api.github.com/users/hazelcast/gists{/gist_id}","starred_url":"https://api.github.com/users/hazelcast/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hazelcast/subscriptions","organizations_url":"https://api.github.com/users/hazelcast/orgs","repos_url":"https://api.github.com/users/hazelcast/repos","events_url":"https://api.github.com/users/hazelcast/events{/privacy}","received_events_url":"https://api.github.com/users/hazelcast/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/hazelcast/hazelcast","description":"Open Source In-Memory Data Grid","fork":false,"url":"https://api.github.com/repos/hazelcast/hazelcast","forks_url":"https://api.github.com/repos/hazelcast/hazelcast/forks","keys_url":"https://api.github.com/repos/hazelcast/hazelcast/keys{/key_id}","collaborators_url":"https://api.github.com/repos/hazelcast/hazelcast/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/hazelcast/hazelcast/teams","hooks_url":"https://api.github.com/repos/hazelcast/hazelcast/hooks","issue_events_url":"https://api.github.com/repos/hazelcast/hazelcast/issues/events{/number}","events_url":"https://api.github.com/repos/hazelcast/hazelcast/events","assignees_url":"https://api.github.com/repos/hazelcast/hazelcast/assignees{/user}","branches_url":"https://api.github.com/repos/hazelcast/hazelcast/branches{/branch}","tags_url":"https://api.github.com/repos/hazelcast/hazelcast/tags","blobs_url":"https://api.github.com/repos/hazelcast/hazelcast/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/hazelcast/hazelcast/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/hazelcast/hazelcast/git/refs{/sha}","trees_url":"https://api.github.com/repos/hazelcast/hazelcast/git/trees{/sha}","statuses_url":"https://api.github.com/repos/hazelcast/hazelcast/statuses/{sha}","languages_url":"https://api.github.com/repos/hazelcast/hazelcast/languages","stargazers_url":"https://api.github.com/repos/hazelcast/hazelcast/stargazers","contributors_url":"https://api.github.com/repos/hazelcast/hazelcast/contributors","subscribers_url":"https://api.github.com/repos/hazelcast/hazelcast/subscribers","subscription_url":"https://api.github.com/repos/hazelcast/hazelcast/subscription","commits_url":"https://api.github.com/repos/hazelcast/hazelcast/commits{/sha}","git_commits_url":"https://api.github.com/repos/hazelcast/hazelcast/git/commits{/sha}","comments_url":"https://api.github.com/repos/hazelcast/hazelcast/comments{/number}","issue_comment_url":"https://api.github.com/repos/hazelcast/hazelcast/issues/comments{/number}","contents_url":"https://api.github.com/repos/hazelcast/hazelcast/contents/{+path}","compare_url":"https://api.github.com/repos/hazelcast/hazelcast/compare/{base}...{head}","merges_url":"https://api.github.com/repos/hazelcast/hazelcast/merges","archive_url":"https://api.github.com/repos/hazelcast/hazelcast/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/hazelcast/hazelcast/downloads","issues_url":"https://api.github.com/repos/hazelcast/hazelcast/issues{/number}","pulls_url":"https://api.github.com/repos/hazelcast/hazelcast/pulls{/number}","milestones_url":"https://api.github.com/repos/hazelcast/hazelcast/milestones{/number}","notifications_url":"https://api.github.com/repos/hazelcast/hazelcast/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/hazelcast/hazelcast/labels{/name}","releases_url":"https://api.github.com/repos/hazelcast/hazelcast/releases{/id}","deployments_url":"https://api.github.com/repos/hazelcast/hazelcast/deployments","created_at":"2012-03-21T12:25:18Z","updated_at":"2018-09-20T07:06:55Z","pushed_at":"2018-09-20T07:06:44Z","git_url":"git://github.com/hazelcast/hazelcast.git","ssh_url":"git@github.com:hazelcast/hazelcast.git","clone_url":"https://github.com/hazelcast/hazelcast.git","svn_url":"https://github.com/hazelcast/hazelcast","homepage":"http://www.hazelcast.org","size":135075,"stargazers_count":2751,"watchers_count":2751,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1062,"mirror_url":null,"archived":false,"open_issues_count":671,"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":1062,"open_issues":671,"watchers":2751,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/hazelcast/hazelcast/pulls/13806"},"html":{"href":"https://github.com/hazelcast/hazelcast/pull/13806"},"issue":{"href":"https://api.github.com/repos/hazelcast/hazelcast/issues/13806"},"comments":{"href":"https://api.github.com/repos/hazelcast/hazelcast/issues/13806/comments"},"review_comments":{"href":"https://api.github.com/repos/hazelcast/hazelcast/pulls/13806/comments"},"review_comment":{"href":"https://api.github.com/repos/hazelcast/hazelcast/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/hazelcast/hazelcast/pulls/13806/commits"},"statuses":{"href":"https://api.github.com/repos/hazelcast/hazelcast/statuses/8e043d703b56e8433f28be31a0d9c2f707c81ffd"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"pveentjer"}}