{"action":"created","comment":{"url":"https://api.github.com/repos/real-logic/Aeron/pulls/comments/29566875","id":29566875,"diff_hunk":"@@ -0,0 +1,462 @@\n+/*\n+ * Copyright 2015 Kaazing Corporation\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+package uk.co.real_logic.aeron.tools;\n+\n+import java.io.InputStream;\n+import java.util.zip.CRC32;\n+\n+import uk.co.real_logic.agrona.DirectBuffer;\n+import uk.co.real_logic.agrona.concurrent.UnsafeBuffer;\n+\n+public class MessageStream\n+{\n+    /* Message header offsets for verifiable message headers. */\n+    private static final int MAGIC_OFFSET = 0;\n+    private static final int MESSAGE_CHECKSUM_OFFSET = 4;\n+    private static final int SEQUENCE_NUMBER_OFFSET = 8;\n+    private final int messageOffset; /* Either 0 or 16, depending on if a verifiable message header is used. */\n+\n+    private static final int HEADER_LENGTH = 16;\n+\n+    private static final int MAGIC = 0x0dd01221; /* That's \"2112d00d\" when taken a byte at a time... */\n+    private static final int MAGIC_END = 0xbeba1221; /* That's \"2112babe\" when taken a byte at a time... */\n+\n+    private static final int HEX_PRINT_WIDTH = 16;\n+\n+    private final int minSize;\n+    private final int maxSize;\n+    private final boolean verifiable;\n+\n+    private InputStream inputStream;\n+    private final boolean inputStreamIsRandom;\n+    private byte[] inputStreamBytes;\n+\n+    private long sequenceNumber = -1;\n+    private long messageCount = 0;\n+    private boolean active = true;\n+\n+    private static final ThreadLocalCRC32 MSG_CHECKSUM = new ThreadLocalCRC32();\n+\n+    private static class ThreadLocalCRC32 extends ThreadLocal<CRC32>\n+    {\n+        @Override protected CRC32 initialValue()\n+        {\n+            return new CRC32();\n+        }\n+    }\n+\n+    public MessageStream(final int size) throws Exception\n+    {\n+        this(size, size, true, null);\n+    }\n+\n+    public MessageStream(final int minSize, final int maxSize) throws Exception\n+    {\n+        this(minSize, maxSize, true, null);\n+    }\n+\n+    public MessageStream(final int size, final InputStream inputStream) throws Exception\n+    {\n+        this(size, size, true, inputStream);\n+    }\n+\n+    public MessageStream(final int size, final boolean verifiable, final InputStream inputStream) throws Exception\n+    {\n+        this(size, size, verifiable, inputStream);\n+    }\n+\n+    public MessageStream(final int minSize, final int maxSize, final boolean verifiable) throws Exception\n+    {\n+        this(minSize, maxSize, verifiable, null);\n+    }\n+\n+    public MessageStream(final int minSize, final int maxSize, final boolean verifiable,\n+            final InputStream inputStream) throws Exception\n+    {\n+        if (this.inputStream == null)\n+        {\n+            // When no input stream is supplied, use random generator.\n+            this.inputStream = new RandomInputStream();\n+            this.inputStreamIsRandom = true;\n+        }\n+        else\n+        {\n+            this.inputStream = inputStream;\n+            this.inputStreamIsRandom = false;\n+        }\n+        if (minSize < 0)\n+        {\n+            throw new Exception(\"MessageStream minimum message size must be 0 or greater.\");\n+        }\n+        if (maxSize < 0)\n+        {\n+            throw new Exception(\"MessageStream maximum message size must be 0 or greater.\");\n+        }\n+        if (maxSize < minSize)\n+        {\n+            throw new Exception(\"MessageStream maximum size must be greater than or equal to minimum size.\");\n+        }\n+        if (verifiable && (minSize < HEADER_LENGTH))\n+        {\n+            throw new Exception(\"MessageStream minimum size must be at least \" +\n+                    HEADER_LENGTH + \" bytes when using verifiable messages.\");\n+        }\n+\n+        this.inputStreamBytes = new byte[maxSize];\n+\n+        this.minSize = minSize;\n+        this.maxSize = maxSize;\n+\n+        this.verifiable = verifiable;\n+        if (this.verifiable)\n+        {\n+            this.messageOffset = HEADER_LENGTH;\n+        }\n+        else\n+        {\n+            this.messageOffset = 0;\n+        }\n+\n+        if (this.minSize > this.maxSize)\n+        {\n+            throw new Exception(\"MessageStream maximum size must be greater than or equal to minimum size.\");\n+        }\n+    }\n+\n+    /** Constructor for the subscribing side. */\n+    public MessageStream()\n+    {\n+        this.minSize = 0;\n+        this.maxSize = 0;\n+        this.messageOffset = HEADER_LENGTH;\n+        this.verifiable = true;\n+        this.inputStream = null;\n+        this.inputStreamIsRandom = false;\n+    }\n+\n+    public int payloadOffset(final DirectBuffer buffer, final int offset)\n+    {\n+        if (isVerifiable(buffer, offset))\n+        {\n+            return HEADER_LENGTH;\n+        }\n+        return 0;\n+    }\n+\n+    public void putNext(final DirectBuffer buffer, final int offset, final int length) throws Exception\n+    {\n+        if (!active)\n+        {\n+            throw new Exception(\"Stream has ended.\");\n+        }\n+\n+        /* Assume we've already checked and it appears we have a verifiable message. */\n+\n+        /* Sequence number check first. */\n+        final long receivedSequenceNumber = buffer.getLong(offset + SEQUENCE_NUMBER_OFFSET);\n+        final long expectedSequenceNumber = sequenceNumber + 1;\n+        if (receivedSequenceNumber != expectedSequenceNumber)\n+        {\n+            final Exception e = new Exception(\"Verifiable message stream received sequence number \" +\n+                    receivedSequenceNumber + \", but was expecting \" +\n+                    expectedSequenceNumber + \". Possibly missed \" +\n+                    (receivedSequenceNumber - expectedSequenceNumber) +\n+                    \" messages.\");\n+            /* Update expected SQN for next time. */\n+            sequenceNumber = receivedSequenceNumber;\n+            throw e;\n+        }\n+\n+        /* Update SQN for next time. */\n+        sequenceNumber++;\n+\n+        /* Calculate the checksum - substituting 0's for the checksum\n+         * field itself - and then compare it to the received checksum\n+         * field. */\n+        final CRC32 crc = MSG_CHECKSUM.get();\n+        crc.reset();\n+        int i = offset;\n+        for (; i < (offset + MESSAGE_CHECKSUM_OFFSET); i++)\n+        {\n+            crc.update(buffer.getByte(i));\n+        }\n+        for (; i < (offset + SEQUENCE_NUMBER_OFFSET); i++)\n+        {\n+            crc.update(0);\n+        }\n+        for (; i < (offset + length); i++)\n+        {\n+            crc.update(buffer.getByte(i));\n+        }\n+\n+        final int msgCksum = buffer.getInt(offset + MESSAGE_CHECKSUM_OFFSET);\n+        if ((int)(crc.getValue()) != msgCksum)\n+        {\n+            throw new Exception(\"Verifiable message per-message checksum invalid; received \" +\n+                    msgCksum + \" but calculated \" + (int)(crc.getValue()));\n+        }\n+\n+        messageCount++;\n+        /* Look for an end marker. */\n+        if (buffer.getInt(offset + MAGIC_OFFSET) == MAGIC_END)\n+        {\n+            active = false;\n+        }\n+    }\n+\n+    public void reset(final InputStream inputStream)\n+    {\n+        reset();\n+        this.inputStream = inputStream;\n+    }\n+\n+    public void reset()\n+    {\n+        /* Reset stream checksum and set things back to active, 0 messages, etc. */\n+        active = true;\n+        messageCount = 0;\n+        sequenceNumber = -1;\n+    }\n+\n+    /**\n+     * Returns whether the MessageStream is still active\n+     * (ie, has not ended if, for example, a file was being sent).\n+     * @return true if the stream is still expecting to generate\n+     * or receive more messages, false otherwise\n+     */\n+    public boolean isActive()\n+    {\n+        return active;\n+    }\n+\n+    /**\n+     * Returns the number of messages that have been either generated (if\n+     * this is a publisher-side MessageStream) or inserted (if this is a\n+     * subscriber-side MessageStream).\n+     * @return the number of messages that have been either generated\n+     * from or inserted into the MessageStream\n+     */\n+    public long getMessageCount()\n+    {\n+        return messageCount;\n+    }\n+\n+    /**\n+     * Gets the current sequence number of the MessageStream; for a\n+     * publisher-side MessageStream, this is the sequence number of\n+     * the last message that was generated.  For a subscriber-side\n+     * MessageStream, this is the sequence number of the last message\n+     * inserted.  If no messages have yet been generated or inserted,\n+     * this will return -1.\n+     * @return the MessageStream's current sequence number, or -1 if no\n+     * messages have been generated or inserted\n+     */\n+    public long getSequenceNumber()\n+    {\n+        return sequenceNumber;\n+    }\n+\n+    /** Returns true if the buffer is _probably_ a verifiable message, false otherwise.\n+     * This method just looks for a magic word at the beginning of the message; random\n+     * data might happen to reproduce one of the magic words about 1 in 2 billion\n+     * times.\n+     * @param buffer Buffer with a message that may or may not be a verifiable message\n+     * @param offset Offset within the buffer where the message starts\n+     * @return true if the message appears to be a verifiable message, false otherwise\n+     */\n+    public static boolean isVerifiable(final DirectBuffer buffer, final int offset)\n+    {\n+        if ((buffer.capacity() - offset) < HEADER_LENGTH)\n+        {\n+            return false;\n+        }\n+        final int magic = buffer.getInt(offset);\n+        if ((magic == MAGIC) || (magic == MAGIC_END))\n+        {\n+            return true;\n+        }\n+        return false;\n+    }\n+\n+    static void printHex(final DirectBuffer buffer, final int length)\n+    {\n+        printHex(buffer, 0, length);\n+    }\n+\n+    static void printHex(final UnsafeBuffer buffer, final int length)\n+    {\n+        printHex(buffer, 0, length);\n+    }\n+\n+    static void printHex(final UnsafeBuffer buffer, final int offset, final int length)\n+    {\n+        int pos = 0;\n+        for (int i = offset; i < (offset + length); i++)\n+        {\n+            System.out.printf(\"%02x \", buffer.getByte(i));\n+            if (++pos % HEX_PRINT_WIDTH == 0)\n+            {\n+                System.out.println();\n+            }\n+        }\n+        System.out.println();\n+    }\n+\n+    public static void printHex(final DirectBuffer buffer, final int offset, final int length)\n+    {\n+        int pos = 0;\n+        for (int i = offset; i < (offset + length); i++)\n+        {\n+            System.out.printf(\"%02x \", buffer.getByte(i));\n+            if (++pos % HEX_PRINT_WIDTH == 0)\n+            {\n+                System.out.println();\n+            }\n+        }\n+        System.out.println();\n+    }\n+\n+    /** Generates a message of random (within the constraints the MessageStream was","path":"aeron-tools/src/main/java/uk/co/real_logic/aeron/tools/MessageStream.java","position":332,"original_position":332,"commit_id":"bd3b61562f1eaaa7c48409afca44c6117203cc6a","original_commit_id":"7da4480cf7afb219e78d9fcb163d28d126a3da39","user":{"login":"strangelydim","id":2837339,"avatar_url":"https://avatars.githubusercontent.com/u/2837339?v=3","gravatar_id":"","url":"https://api.github.com/users/strangelydim","html_url":"https://github.com/strangelydim","followers_url":"https://api.github.com/users/strangelydim/followers","following_url":"https://api.github.com/users/strangelydim/following{/other_user}","gists_url":"https://api.github.com/users/strangelydim/gists{/gist_id}","starred_url":"https://api.github.com/users/strangelydim/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/strangelydim/subscriptions","organizations_url":"https://api.github.com/users/strangelydim/orgs","repos_url":"https://api.github.com/users/strangelydim/repos","events_url":"https://api.github.com/users/strangelydim/events{/privacy}","received_events_url":"https://api.github.com/users/strangelydim/received_events","type":"User","site_admin":false},"body":"As I'm going through and adding newlines, it's looking really ridiculous doing it for one-line docs like this:\r\n\r\n```\r\n/** Application should print advanced usage guide with help */\r\nboolean showUsage;\r\n```\r\n\r\nDo you really want those to look like this instead?:\r\n\r\n```\r\n/**\r\n * Application should print advanced usage guide with help */\r\nboolean showUsage;\r\n```","created_at":"2015-05-04T05:39:38Z","updated_at":"2015-05-04T05:39:38Z","html_url":"https://github.com/real-logic/Aeron/pull/108#discussion_r29566875","pull_request_url":"https://api.github.com/repos/real-logic/Aeron/pulls/108","_links":{"self":{"href":"https://api.github.com/repos/real-logic/Aeron/pulls/comments/29566875"},"html":{"href":"https://github.com/real-logic/Aeron/pull/108#discussion_r29566875"},"pull_request":{"href":"https://api.github.com/repos/real-logic/Aeron/pulls/108"}}},"pull_request":{"url":"https://api.github.com/repos/real-logic/Aeron/pulls/108","id":34506965,"html_url":"https://github.com/real-logic/Aeron/pull/108","diff_url":"https://github.com/real-logic/Aeron/pull/108.diff","patch_url":"https://github.com/real-logic/Aeron/pull/108.patch","issue_url":"https://api.github.com/repos/real-logic/Aeron/issues/108","number":108,"state":"open","locked":false,"title":"Doc, packaging, and tools for Aeron","user":{"login":"strangelydim","id":2837339,"avatar_url":"https://avatars.githubusercontent.com/u/2837339?v=3","gravatar_id":"","url":"https://api.github.com/users/strangelydim","html_url":"https://github.com/strangelydim","followers_url":"https://api.github.com/users/strangelydim/followers","following_url":"https://api.github.com/users/strangelydim/following{/other_user}","gists_url":"https://api.github.com/users/strangelydim/gists{/gist_id}","starred_url":"https://api.github.com/users/strangelydim/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/strangelydim/subscriptions","organizations_url":"https://api.github.com/users/strangelydim/orgs","repos_url":"https://api.github.com/users/strangelydim/repos","events_url":"https://api.github.com/users/strangelydim/events{/privacy}","received_events_url":"https://api.github.com/users/strangelydim/received_events","type":"User","site_admin":false},"body":"This is a big one...  Tools for performance testing and graph generation, for testing Aeron in general with multiple publications/subscriptions and channels and sending/receiving threads, abuse testing, some new and updated sample apps, new doc, and a test plan.\r\n\r\nLet me know if changes need to be made before acceptance.  (Or if you'd like to accept first just to get this all in and make changes later via another pull request.)","created_at":"2015-04-30T22:21:43Z","updated_at":"2015-05-04T05:39:38Z","closed_at":null,"merged_at":null,"merge_commit_sha":"3d523edef184f1662a6b61d900860cca1d85b1be","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/real-logic/Aeron/pulls/108/commits","review_comments_url":"https://api.github.com/repos/real-logic/Aeron/pulls/108/comments","review_comment_url":"https://api.github.com/repos/real-logic/Aeron/pulls/comments{/number}","comments_url":"https://api.github.com/repos/real-logic/Aeron/issues/108/comments","statuses_url":"https://api.github.com/repos/real-logic/Aeron/statuses/bd3b61562f1eaaa7c48409afca44c6117203cc6a","head":{"label":"strangelydim:real-logic-pull-request","ref":"real-logic-pull-request","sha":"bd3b61562f1eaaa7c48409afca44c6117203cc6a","user":{"login":"strangelydim","id":2837339,"avatar_url":"https://avatars.githubusercontent.com/u/2837339?v=3","gravatar_id":"","url":"https://api.github.com/users/strangelydim","html_url":"https://github.com/strangelydim","followers_url":"https://api.github.com/users/strangelydim/followers","following_url":"https://api.github.com/users/strangelydim/following{/other_user}","gists_url":"https://api.github.com/users/strangelydim/gists{/gist_id}","starred_url":"https://api.github.com/users/strangelydim/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/strangelydim/subscriptions","organizations_url":"https://api.github.com/users/strangelydim/orgs","repos_url":"https://api.github.com/users/strangelydim/repos","events_url":"https://api.github.com/users/strangelydim/events{/privacy}","received_events_url":"https://api.github.com/users/strangelydim/received_events","type":"User","site_admin":false},"repo":{"id":31387795,"name":"Aeron","full_name":"strangelydim/Aeron","owner":{"login":"strangelydim","id":2837339,"avatar_url":"https://avatars.githubusercontent.com/u/2837339?v=3","gravatar_id":"","url":"https://api.github.com/users/strangelydim","html_url":"https://github.com/strangelydim","followers_url":"https://api.github.com/users/strangelydim/followers","following_url":"https://api.github.com/users/strangelydim/following{/other_user}","gists_url":"https://api.github.com/users/strangelydim/gists{/gist_id}","starred_url":"https://api.github.com/users/strangelydim/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/strangelydim/subscriptions","organizations_url":"https://api.github.com/users/strangelydim/orgs","repos_url":"https://api.github.com/users/strangelydim/repos","events_url":"https://api.github.com/users/strangelydim/events{/privacy}","received_events_url":"https://api.github.com/users/strangelydim/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/strangelydim/Aeron","description":"Efficient reliable unicast and multicast message transport","fork":true,"url":"https://api.github.com/repos/strangelydim/Aeron","forks_url":"https://api.github.com/repos/strangelydim/Aeron/forks","keys_url":"https://api.github.com/repos/strangelydim/Aeron/keys{/key_id}","collaborators_url":"https://api.github.com/repos/strangelydim/Aeron/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/strangelydim/Aeron/teams","hooks_url":"https://api.github.com/repos/strangelydim/Aeron/hooks","issue_events_url":"https://api.github.com/repos/strangelydim/Aeron/issues/events{/number}","events_url":"https://api.github.com/repos/strangelydim/Aeron/events","assignees_url":"https://api.github.com/repos/strangelydim/Aeron/assignees{/user}","branches_url":"https://api.github.com/repos/strangelydim/Aeron/branches{/branch}","tags_url":"https://api.github.com/repos/strangelydim/Aeron/tags","blobs_url":"https://api.github.com/repos/strangelydim/Aeron/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/strangelydim/Aeron/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/strangelydim/Aeron/git/refs{/sha}","trees_url":"https://api.github.com/repos/strangelydim/Aeron/git/trees{/sha}","statuses_url":"https://api.github.com/repos/strangelydim/Aeron/statuses/{sha}","languages_url":"https://api.github.com/repos/strangelydim/Aeron/languages","stargazers_url":"https://api.github.com/repos/strangelydim/Aeron/stargazers","contributors_url":"https://api.github.com/repos/strangelydim/Aeron/contributors","subscribers_url":"https://api.github.com/repos/strangelydim/Aeron/subscribers","subscription_url":"https://api.github.com/repos/strangelydim/Aeron/subscription","commits_url":"https://api.github.com/repos/strangelydim/Aeron/commits{/sha}","git_commits_url":"https://api.github.com/repos/strangelydim/Aeron/git/commits{/sha}","comments_url":"https://api.github.com/repos/strangelydim/Aeron/comments{/number}","issue_comment_url":"https://api.github.com/repos/strangelydim/Aeron/issues/comments{/number}","contents_url":"https://api.github.com/repos/strangelydim/Aeron/contents/{+path}","compare_url":"https://api.github.com/repos/strangelydim/Aeron/compare/{base}...{head}","merges_url":"https://api.github.com/repos/strangelydim/Aeron/merges","archive_url":"https://api.github.com/repos/strangelydim/Aeron/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/strangelydim/Aeron/downloads","issues_url":"https://api.github.com/repos/strangelydim/Aeron/issues{/number}","pulls_url":"https://api.github.com/repos/strangelydim/Aeron/pulls{/number}","milestones_url":"https://api.github.com/repos/strangelydim/Aeron/milestones{/number}","notifications_url":"https://api.github.com/repos/strangelydim/Aeron/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/strangelydim/Aeron/labels{/name}","releases_url":"https://api.github.com/repos/strangelydim/Aeron/releases{/id}","created_at":"2015-02-26T20:42:10Z","updated_at":"2015-04-30T21:10:22Z","pushed_at":"2015-05-04T05:30:59Z","git_url":"git://github.com/strangelydim/Aeron.git","ssh_url":"git@github.com:strangelydim/Aeron.git","clone_url":"https://github.com/strangelydim/Aeron.git","svn_url":"https://github.com/strangelydim/Aeron","homepage":"","size":12732,"stargazers_count":1,"watchers_count":1,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":1,"forks":1,"open_issues":1,"watchers":1,"default_branch":"master"}},"base":{"label":"real-logic:master","ref":"master","sha":"03bb1177b4ce0da3a93c593c268a503ecb4d89e7","user":{"login":"real-logic","id":5371471,"avatar_url":"https://avatars.githubusercontent.com/u/5371471?v=3","gravatar_id":"","url":"https://api.github.com/users/real-logic","html_url":"https://github.com/real-logic","followers_url":"https://api.github.com/users/real-logic/followers","following_url":"https://api.github.com/users/real-logic/following{/other_user}","gists_url":"https://api.github.com/users/real-logic/gists{/gist_id}","starred_url":"https://api.github.com/users/real-logic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/real-logic/subscriptions","organizations_url":"https://api.github.com/users/real-logic/orgs","repos_url":"https://api.github.com/users/real-logic/repos","events_url":"https://api.github.com/users/real-logic/events{/privacy}","received_events_url":"https://api.github.com/users/real-logic/received_events","type":"Organization","site_admin":false},"repo":{"id":16621659,"name":"Aeron","full_name":"real-logic/Aeron","owner":{"login":"real-logic","id":5371471,"avatar_url":"https://avatars.githubusercontent.com/u/5371471?v=3","gravatar_id":"","url":"https://api.github.com/users/real-logic","html_url":"https://github.com/real-logic","followers_url":"https://api.github.com/users/real-logic/followers","following_url":"https://api.github.com/users/real-logic/following{/other_user}","gists_url":"https://api.github.com/users/real-logic/gists{/gist_id}","starred_url":"https://api.github.com/users/real-logic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/real-logic/subscriptions","organizations_url":"https://api.github.com/users/real-logic/orgs","repos_url":"https://api.github.com/users/real-logic/repos","events_url":"https://api.github.com/users/real-logic/events{/privacy}","received_events_url":"https://api.github.com/users/real-logic/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/real-logic/Aeron","description":"Efficient reliable unicast and multicast message transport","fork":false,"url":"https://api.github.com/repos/real-logic/Aeron","forks_url":"https://api.github.com/repos/real-logic/Aeron/forks","keys_url":"https://api.github.com/repos/real-logic/Aeron/keys{/key_id}","collaborators_url":"https://api.github.com/repos/real-logic/Aeron/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/real-logic/Aeron/teams","hooks_url":"https://api.github.com/repos/real-logic/Aeron/hooks","issue_events_url":"https://api.github.com/repos/real-logic/Aeron/issues/events{/number}","events_url":"https://api.github.com/repos/real-logic/Aeron/events","assignees_url":"https://api.github.com/repos/real-logic/Aeron/assignees{/user}","branches_url":"https://api.github.com/repos/real-logic/Aeron/branches{/branch}","tags_url":"https://api.github.com/repos/real-logic/Aeron/tags","blobs_url":"https://api.github.com/repos/real-logic/Aeron/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/real-logic/Aeron/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/real-logic/Aeron/git/refs{/sha}","trees_url":"https://api.github.com/repos/real-logic/Aeron/git/trees{/sha}","statuses_url":"https://api.github.com/repos/real-logic/Aeron/statuses/{sha}","languages_url":"https://api.github.com/repos/real-logic/Aeron/languages","stargazers_url":"https://api.github.com/repos/real-logic/Aeron/stargazers","contributors_url":"https://api.github.com/repos/real-logic/Aeron/contributors","subscribers_url":"https://api.github.com/repos/real-logic/Aeron/subscribers","subscription_url":"https://api.github.com/repos/real-logic/Aeron/subscription","commits_url":"https://api.github.com/repos/real-logic/Aeron/commits{/sha}","git_commits_url":"https://api.github.com/repos/real-logic/Aeron/git/commits{/sha}","comments_url":"https://api.github.com/repos/real-logic/Aeron/comments{/number}","issue_comment_url":"https://api.github.com/repos/real-logic/Aeron/issues/comments{/number}","contents_url":"https://api.github.com/repos/real-logic/Aeron/contents/{+path}","compare_url":"https://api.github.com/repos/real-logic/Aeron/compare/{base}...{head}","merges_url":"https://api.github.com/repos/real-logic/Aeron/merges","archive_url":"https://api.github.com/repos/real-logic/Aeron/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/real-logic/Aeron/downloads","issues_url":"https://api.github.com/repos/real-logic/Aeron/issues{/number}","pulls_url":"https://api.github.com/repos/real-logic/Aeron/pulls{/number}","milestones_url":"https://api.github.com/repos/real-logic/Aeron/milestones{/number}","notifications_url":"https://api.github.com/repos/real-logic/Aeron/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/real-logic/Aeron/labels{/name}","releases_url":"https://api.github.com/repos/real-logic/Aeron/releases{/id}","created_at":"2014-02-07T17:16:58Z","updated_at":"2015-05-03T20:53:07Z","pushed_at":"2015-05-04T05:31:00Z","git_url":"git://github.com/real-logic/Aeron.git","ssh_url":"git@github.com:real-logic/Aeron.git","clone_url":"https://github.com/real-logic/Aeron.git","svn_url":"https://github.com/real-logic/Aeron","homepage":"","size":20909,"stargazers_count":1022,"watchers_count":1022,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":121,"mirror_url":null,"open_issues_count":24,"forks":121,"open_issues":24,"watchers":1022,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/real-logic/Aeron/pulls/108"},"html":{"href":"https://github.com/real-logic/Aeron/pull/108"},"issue":{"href":"https://api.github.com/repos/real-logic/Aeron/issues/108"},"comments":{"href":"https://api.github.com/repos/real-logic/Aeron/issues/108/comments"},"review_comments":{"href":"https://api.github.com/repos/real-logic/Aeron/pulls/108/comments"},"review_comment":{"href":"https://api.github.com/repos/real-logic/Aeron/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/real-logic/Aeron/pulls/108/commits"},"statuses":{"href":"https://api.github.com/repos/real-logic/Aeron/statuses/bd3b61562f1eaaa7c48409afca44c6117203cc6a"}}}}