{"action":"created","comment":{"url":"https://api.github.com/repos/Comcast/jrugged/pulls/comments/50564916","id":50564916,"diff_hunk":"@@ -0,0 +1,471 @@\n+/* SkepticBreaker.java\n+ *\n+ * Copyright 2009-2015 Comcast Interactive Media, LLC.\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 org.fishwife.jrugged;\n+\n+import java.util.concurrent.Callable;\n+import java.util.concurrent.atomic.AtomicLong;\n+\n+import org.fishwife.jrugged.Breaker.BreakerState;\n+import static org.easymock.EasyMock.createMock;\n+\n+/** A {@link SkepticBreaker} can be used with a service to throttle traffic\n+ *  to a failed subsystem (particularly one we might not be able to monitor,\n+ *  such as a peer system which must be accessed over the network). Service\n+ *  calls are wrapped by the <code>SkepticBreaker</code>.\n+ *  <p>\n+ *  When everything is operating normally, the <code>SkepticBreaker</code>\n+ *  is CLOSED and the calls are allowed through. If the 'good timer' runs out\n+ *  while in CLOSED state, Skepticism level decreases. \n+ *  <p>\n+ *  When a call fails, however, the <code>SkepticBreaker</code> \"trips\" and\n+ *  moves to an OPEN state. Skepticism level increases. Client calls are not \n+ *  allowed through while the <code>SkepticBreaker</code> is OPEN.\n+ *  <p>\n+ *  After a certain \"cooldown\" period where calls are not allowed to go through \n+ *  but internal sample calls are made, if no bad calls are encountered after the\n+ *  cooldown timer runs out (wait time), the <code>SkepticBreaker</code> will \n+ *  transition back to a CLOSED state. If bad calls are made, the timer restarts.\n+ *  <p>\n+ *  Sample usage:\n+ *  <pre>\n+    public class Service implements Monitorable {\n+        private SkepticBreaker cb = new SkepticBreaker();\n+        public String doSomething(final Object arg) throws Exception {\n+        return cb.invoke(new Callable&lt;String&gt;() {\n+                                 public String call() {\n+                                     // make the call ...\n+                                 }\n+                             });\n+        }\n+        public Status getStatus() { return cb.getStatus(); }\n+    }\n+ * </pre>\n+ */\n+public class SkepticBreaker extends Breaker implements MonitoredService, ServiceWrapper {\n+ \n+    /** The time the breaker last switched into good/CLOSED state. */\n+    protected AtomicLong lastCloseTime = new AtomicLong(System.currentTimeMillis()); \n+\n+    /** Variables added to determine Wait Timer and Good Timer */\n+    protected AtomicLong waitBase = new AtomicLong(1000L);\n+    protected AtomicLong waitMult = new AtomicLong(100L);\n+    protected AtomicLong goodBase = new AtomicLong(600000L);\n+    protected AtomicLong goodMult = new AtomicLong(100L);\n+    protected AtomicLong skepticLevel = new AtomicLong(0L);\n+    protected AtomicLong maxLevel = new AtomicLong(20L);\n+    \n+    /** How long the cooldown period is in milliseconds during Wait Phase. */\n+    protected AtomicLong waitTime = new AtomicLong((long) (waitBase.get() + \n+    \t\twaitMult.get() * Math.pow(2, skepticLevel.get())));\n+   \n+    /** How long the cooldown period is in milliseconds during Good Phase. */\n+    protected AtomicLong goodTime = new AtomicLong((long) (goodBase.get() + \n+    \t\tgoodMult.get() * Math.pow(2, skepticLevel.get())));\n+\n+    /** The default name if none is provided. */\n+    private static final String DEFAULT_NAME = \"SkepticBreaker\";\n+    \n+    /** The name for the SkepticBreaker. */\n+    protected String name = DEFAULT_NAME;\n+    \n+    /** Creates a {@link SkepticBreaker} with a {@link\n+     *  DefaultFailureInterpreter} and the default \"tripped\" exception\n+     *  behavior (throwing a {@link BreakerException}). */\n+    public SkepticBreaker() {\n+    }\n+    \n+    /** Creates a {@link SkepticBreaker} with a {@link\n+     *  DefaultFailureInterpreter} and the default \"tripped\" exception\n+     *  behavior (throwing a {@link BreakerException}).\n+     *  @param name the name for the {@link SkepticBreaker}.\n+     */\n+    public SkepticBreaker(String name) {\n+        super(name);\n+    }\n+\n+    /** Creates a {@link SkepticBreaker} with the specified {@link\n+     *    FailureInterpreter} and the default \"tripped\" exception\n+     *    behavior (throwing a {@link BreakerException}).\n+     *  @param fi the <code>FailureInterpreter</code> to use when\n+     *    determining whether a specific failure ought to cause the\n+     *    breaker to trip\n+     */\n+    public SkepticBreaker(FailureInterpreter fi) {\n+        super(fi);\n+    }\n+\n+    /** Creates a {@link SkepticBreaker} with the specified {@link\n+     *    FailureInterpreter} and the default \"tripped\" exception\n+     *    behavior (throwing a {@link BreakerException}).\n+     *  @param name the name for the {@link SkepticBreaker}.\n+     *  @param fi the <code>FailureInterpreter</code> to use when\n+     *    determining whether a specific failure ought to cause the\n+     *    breaker to trip\n+     */\n+    public SkepticBreaker(String name, FailureInterpreter fi) {\n+        super(name, fi);\n+    }\n+\n+    /** Creates a {@link SkepticBreaker} with a {@link\n+     *  DefaultFailureInterpreter} and using the supplied {@link\n+     *  BreakerExceptionMapper} when client calls are made\n+     *  while the breaker is tripped.\n+     *  @param name the name for the {@link SkepticBreaker}.\n+     *  @param mapper helper used to translate a {@link\n+     *    BreakerException} into an application-specific one */\n+    public SkepticBreaker(String name, BreakerExceptionMapper<? extends Exception> mapper) {\n+        super(name, mapper);\n+    }\n+\n+    /** Creates a {@link SkepticBreaker} with the provided {@link\n+     *  FailureInterpreter} and using the provided {@link\n+     *  BreakerExceptionMapper} when client calls are made\n+     *  while the breaker is tripped.\n+     *  @param name the name for the {@link SkepticBreaker}.\n+     *  @param fi the <code>FailureInterpreter</code> to use when\n+     *    determining whether a specific failure ought to cause the\n+     *    breaker to trip\n+     *  @param mapper helper used to translate a {@link\n+     *    BreakerException} into an application-specific one */\n+    public SkepticBreaker(String name,\n+                          FailureInterpreter fi,\n+                          BreakerExceptionMapper<? extends Exception> mapper) {\n+        super(name, fi, mapper);\n+    }\n+\n+    /** Wrap the given service call with the {@link SkepticBreaker}\n+     *  protection logic.\n+     *  @param c the {@link Callable} to attempt\n+     *  @return whatever c would return on success\n+     *  @throws BreakerException if the\n+     *    breaker was OPEN and this attempt wasn't the\n+     *    reset attempt\n+     *  @throws Exception if <code>c</code> throws one during\n+     *    execution\n+     */ \n+    public <V> V invoke(Callable<V> c) throws Exception {\n+        if (!byPass) {\n+            if (!allowRequest()) {\n+            \tif (!isHardTrip) {\n+            \t\ttry {\n+            \t\t    Callable<Object> mockCallable = createMock(Callable.class);\n+            \t\t    mockCallable.call();\n+            \t\t}\n+            \t\tcatch (Throwable cause) {\n+            \t\t\thandleFailure(cause); \n+            \t\t}\n+            \t}\n+                throw mapException(new BreakerException());\n+            }\n+\n+            try {\n+                V result = c.call();\n+                close();\n+                return result;\n+            } catch (Throwable cause) {\n+                handleFailure(cause);\n+            }\n+            throw new IllegalStateException(\"not possible\");\n+        }\n+        else {\n+            return c.call();\n+        }\n+    }\n+\n+    /** Wrap the given service call with the {@link SkepticBreaker}\n+     *  protection logic.\n+     *  @param r the {@link Runnable} to attempt\n+     *  @throws BreakerException if the\n+     *    breaker was OPEN and this attempt wasn't the\n+     *    reset attempt\n+     *  @throws Exception if <code>c</code> throws one during\n+     *    execution\n+     */\n+    public void invoke(Runnable r) throws Exception {\n+        if (!byPass) {\n+            if (!allowRequest()) {\n+            \tif(!isHardTrip){\n+            \t\ttry{\n+            \t\t\tRunnable mockRunnable = createMock(Runnable.class);\n+            \t\t    mockRunnable.run(); \n+            \t\t}\n+            \t\tcatch (Throwable cause){\n+            \t\t\thandleFailure(cause); \n+            \t\t}\n+            \t}\n+                throw mapException(new BreakerException());\n+            }\n+\n+            try {\n+                r.run();\n+                close();\n+                return;\n+            } catch (Throwable cause) {\n+                handleFailure(cause);\n+            }\n+            throw new IllegalStateException(\"not possible\");\n+        }\n+        else {\n+            r.run();\n+        }\n+    }\n+\n+    /** Wrap the given service call with the {@link SkepticBreaker}\n+     *  protection logic.\n+     *  @param r the {@link Runnable} to attempt\n+     *  @param result what to return after <code>r</code> succeeds\n+     *  @return result\n+     *  @throws BreakerException if the\n+     *    breaker was OPEN and this attempt wasn't the\n+     *    reset attempt\n+     *  @throws Exception if <code>c</code> throws one during\n+     *    execution\n+     */\n+    public <V> V invoke(Runnable r, V result) throws Exception {\n+        if (!byPass) {\n+            if (!allowRequest()) {\n+            \tif(!isHardTrip){\n+            \t\ttry{\n+            \t\t\tRunnable mockRunnable = createMock(Runnable.class);\n+            \t\t    mockRunnable.run(); \n+            \t\t}\n+            \t\tcatch (Throwable cause){\n+            \t\t\thandleFailure(cause); \n+            \t\t}\n+            \t}\n+                throw mapException(new BreakerException());\n+            }\n+\n+            try {\n+                r.run();\n+                close();\n+                return result;\n+            } catch (Throwable cause) {\n+                handleFailure(cause);\n+            }\n+            throw new IllegalStateException(\"not possible\");\n+        }\n+        else {\n+            r.run();\n+            return result;\n+        }\n+    }\n+\n+    /**\n+     * Causes the {@link SkepticBreaker} to trip and OPEN; no new\n+     *  requests will be allowed until the <code>SkepticBreaker</code>\n+     *  resets. Skeptic level increases and timers are updated accordingly.\n+     */\n+    public void trip() {\n+    \tif (state != BreakerState.OPEN) {\n+            openCount.getAndIncrement();\n+        }\n+    \tif (skepticLevel.get() < maxLevel.get()) {\n+    \t\tincreaseSkepticLevel();\n+    \t}\n+        state = BreakerState.OPEN;\n+        lastFailure.set(System.currentTimeMillis());\n+\n+        notifyBreakerStateChange(getStatus());\n+    }\n+    \n+    /**\n+     * Increments the skeptic level and updates timers; occurs when the \n+     * {@link SkepticBreaker} trips and moves from CLOSED to OPEN\n+     */\n+    public void increaseSkepticLevel() {\n+    \tskepticLevel.set(skepticLevel.incrementAndGet());\n+    \tupdateTimers();\n+    }\n+    \n+    /**\n+     * Updates wait timer and good timer based on current skeptic level.\n+     */\n+    public void updateTimers() {\n+    \twaitTime.set((long) (waitBase.get() + waitMult.get() * Math.pow(2, skepticLevel.get())));\n+    \tgoodTime.set((long) (goodBase.get() + goodMult.get() * Math.pow(2, skepticLevel.get())));\n+    }\n+\n+    /**\n+     * Manually set the breaker to be reset and ready for use.  This\n+     * is only useful after a manual trip otherwise the breaker will\n+     * trip automatically again if the service is still unavailable.\n+     * Just like a real breaker.  WOOT!!!\n+     */\n+    public void reset() {\n+        state = BreakerState.CLOSED;\n+        isHardTrip = false;\n+        byPass = false;\n+        skepticLevel.set(0);","path":"jrugged-core/src/main/java/org/fishwife/jrugged/SkepticBreaker.java","position":313,"original_position":313,"commit_id":"2da3cb21b74057c1ea748ed293037d19f3e2eb0d","original_commit_id":"2da3cb21b74057c1ea748ed293037d19f3e2eb0d","user":{"login":"joercampbell","id":1405374,"avatar_url":"https://avatars.githubusercontent.com/u/1405374?v=3","gravatar_id":"","url":"https://api.github.com/users/joercampbell","html_url":"https://github.com/joercampbell","followers_url":"https://api.github.com/users/joercampbell/followers","following_url":"https://api.github.com/users/joercampbell/following{/other_user}","gists_url":"https://api.github.com/users/joercampbell/gists{/gist_id}","starred_url":"https://api.github.com/users/joercampbell/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/joercampbell/subscriptions","organizations_url":"https://api.github.com/users/joercampbell/orgs","repos_url":"https://api.github.com/users/joercampbell/repos","events_url":"https://api.github.com/users/joercampbell/events{/privacy}","received_events_url":"https://api.github.com/users/joercampbell/received_events","type":"User","site_admin":false},"body":"Silly - but I would likely have put this in a method called resetSkepticLevel() so that it told us what it was being done for.","created_at":"2016-01-22T17:28:29Z","updated_at":"2016-01-22T17:28:29Z","html_url":"https://github.com/Comcast/jrugged/pull/43#discussion_r50564916","pull_request_url":"https://api.github.com/repos/Comcast/jrugged/pulls/43","_links":{"self":{"href":"https://api.github.com/repos/Comcast/jrugged/pulls/comments/50564916"},"html":{"href":"https://github.com/Comcast/jrugged/pull/43#discussion_r50564916"},"pull_request":{"href":"https://api.github.com/repos/Comcast/jrugged/pulls/43"}}},"pull_request":{"url":"https://api.github.com/repos/Comcast/jrugged/pulls/43","id":54010196,"html_url":"https://github.com/Comcast/jrugged/pull/43","diff_url":"https://github.com/Comcast/jrugged/pull/43.diff","patch_url":"https://github.com/Comcast/jrugged/pull/43.patch","issue_url":"https://api.github.com/repos/Comcast/jrugged/issues/43","number":43,"state":"open","locked":false,"title":"SkepticBreaker Implementation","user":{"login":"ekmason12","id":5404513,"avatar_url":"https://avatars.githubusercontent.com/u/5404513?v=3","gravatar_id":"","url":"https://api.github.com/users/ekmason12","html_url":"https://github.com/ekmason12","followers_url":"https://api.github.com/users/ekmason12/followers","following_url":"https://api.github.com/users/ekmason12/following{/other_user}","gists_url":"https://api.github.com/users/ekmason12/gists{/gist_id}","starred_url":"https://api.github.com/users/ekmason12/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ekmason12/subscriptions","organizations_url":"https://api.github.com/users/ekmason12/orgs","repos_url":"https://api.github.com/users/ekmason12/repos","events_url":"https://api.github.com/users/ekmason12/events{/privacy}","received_events_url":"https://api.github.com/users/ekmason12/received_events","type":"User","site_admin":false},"body":"Implemented SkepticBreaker, refactored code between CircuitBreaker and SkepticBreaker, added SkepticBreaker example","created_at":"2015-12-17T18:01:52Z","updated_at":"2016-01-22T17:28:29Z","closed_at":null,"merged_at":null,"merge_commit_sha":"9677ce291ace6b12b53b151abf40a15fab17967f","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/Comcast/jrugged/pulls/43/commits","review_comments_url":"https://api.github.com/repos/Comcast/jrugged/pulls/43/comments","review_comment_url":"https://api.github.com/repos/Comcast/jrugged/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Comcast/jrugged/issues/43/comments","statuses_url":"https://api.github.com/repos/Comcast/jrugged/statuses/2da3cb21b74057c1ea748ed293037d19f3e2eb0d","head":{"label":"ekmason12:skepticBreaker","ref":"skepticBreaker","sha":"2da3cb21b74057c1ea748ed293037d19f3e2eb0d","user":{"login":"ekmason12","id":5404513,"avatar_url":"https://avatars.githubusercontent.com/u/5404513?v=3","gravatar_id":"","url":"https://api.github.com/users/ekmason12","html_url":"https://github.com/ekmason12","followers_url":"https://api.github.com/users/ekmason12/followers","following_url":"https://api.github.com/users/ekmason12/following{/other_user}","gists_url":"https://api.github.com/users/ekmason12/gists{/gist_id}","starred_url":"https://api.github.com/users/ekmason12/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ekmason12/subscriptions","organizations_url":"https://api.github.com/users/ekmason12/orgs","repos_url":"https://api.github.com/users/ekmason12/repos","events_url":"https://api.github.com/users/ekmason12/events{/privacy}","received_events_url":"https://api.github.com/users/ekmason12/received_events","type":"User","site_admin":false},"repo":{"id":42083419,"name":"jrugged","full_name":"ekmason12/jrugged","owner":{"login":"ekmason12","id":5404513,"avatar_url":"https://avatars.githubusercontent.com/u/5404513?v=3","gravatar_id":"","url":"https://api.github.com/users/ekmason12","html_url":"https://github.com/ekmason12","followers_url":"https://api.github.com/users/ekmason12/followers","following_url":"https://api.github.com/users/ekmason12/following{/other_user}","gists_url":"https://api.github.com/users/ekmason12/gists{/gist_id}","starred_url":"https://api.github.com/users/ekmason12/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ekmason12/subscriptions","organizations_url":"https://api.github.com/users/ekmason12/orgs","repos_url":"https://api.github.com/users/ekmason12/repos","events_url":"https://api.github.com/users/ekmason12/events{/privacy}","received_events_url":"https://api.github.com/users/ekmason12/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ekmason12/jrugged","description":"A Java libary of robustness design patterns","fork":true,"url":"https://api.github.com/repos/ekmason12/jrugged","forks_url":"https://api.github.com/repos/ekmason12/jrugged/forks","keys_url":"https://api.github.com/repos/ekmason12/jrugged/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ekmason12/jrugged/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ekmason12/jrugged/teams","hooks_url":"https://api.github.com/repos/ekmason12/jrugged/hooks","issue_events_url":"https://api.github.com/repos/ekmason12/jrugged/issues/events{/number}","events_url":"https://api.github.com/repos/ekmason12/jrugged/events","assignees_url":"https://api.github.com/repos/ekmason12/jrugged/assignees{/user}","branches_url":"https://api.github.com/repos/ekmason12/jrugged/branches{/branch}","tags_url":"https://api.github.com/repos/ekmason12/jrugged/tags","blobs_url":"https://api.github.com/repos/ekmason12/jrugged/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ekmason12/jrugged/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ekmason12/jrugged/git/refs{/sha}","trees_url":"https://api.github.com/repos/ekmason12/jrugged/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ekmason12/jrugged/statuses/{sha}","languages_url":"https://api.github.com/repos/ekmason12/jrugged/languages","stargazers_url":"https://api.github.com/repos/ekmason12/jrugged/stargazers","contributors_url":"https://api.github.com/repos/ekmason12/jrugged/contributors","subscribers_url":"https://api.github.com/repos/ekmason12/jrugged/subscribers","subscription_url":"https://api.github.com/repos/ekmason12/jrugged/subscription","commits_url":"https://api.github.com/repos/ekmason12/jrugged/commits{/sha}","git_commits_url":"https://api.github.com/repos/ekmason12/jrugged/git/commits{/sha}","comments_url":"https://api.github.com/repos/ekmason12/jrugged/comments{/number}","issue_comment_url":"https://api.github.com/repos/ekmason12/jrugged/issues/comments{/number}","contents_url":"https://api.github.com/repos/ekmason12/jrugged/contents/{+path}","compare_url":"https://api.github.com/repos/ekmason12/jrugged/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ekmason12/jrugged/merges","archive_url":"https://api.github.com/repos/ekmason12/jrugged/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ekmason12/jrugged/downloads","issues_url":"https://api.github.com/repos/ekmason12/jrugged/issues{/number}","pulls_url":"https://api.github.com/repos/ekmason12/jrugged/pulls{/number}","milestones_url":"https://api.github.com/repos/ekmason12/jrugged/milestones{/number}","notifications_url":"https://api.github.com/repos/ekmason12/jrugged/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ekmason12/jrugged/labels{/name}","releases_url":"https://api.github.com/repos/ekmason12/jrugged/releases{/id}","deployments_url":"https://api.github.com/repos/ekmason12/jrugged/deployments","created_at":"2015-09-08T01:46:02Z","updated_at":"2015-09-08T01:46:03Z","pushed_at":"2015-12-17T17:52:32Z","git_url":"git://github.com/ekmason12/jrugged.git","ssh_url":"git@github.com:ekmason12/jrugged.git","clone_url":"https://github.com/ekmason12/jrugged.git","svn_url":"https://github.com/ekmason12/jrugged","homepage":null,"size":1071,"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":"Comcast:master","ref":"master","sha":"ba1d390a6ba188fe47f4f0192e9d9f7e7e51e1d0","user":{"login":"Comcast","id":709212,"avatar_url":"https://avatars.githubusercontent.com/u/709212?v=3","gravatar_id":"","url":"https://api.github.com/users/Comcast","html_url":"https://github.com/Comcast","followers_url":"https://api.github.com/users/Comcast/followers","following_url":"https://api.github.com/users/Comcast/following{/other_user}","gists_url":"https://api.github.com/users/Comcast/gists{/gist_id}","starred_url":"https://api.github.com/users/Comcast/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Comcast/subscriptions","organizations_url":"https://api.github.com/users/Comcast/orgs","repos_url":"https://api.github.com/users/Comcast/repos","events_url":"https://api.github.com/users/Comcast/events{/privacy}","received_events_url":"https://api.github.com/users/Comcast/received_events","type":"Organization","site_admin":false},"repo":{"id":6602723,"name":"jrugged","full_name":"Comcast/jrugged","owner":{"login":"Comcast","id":709212,"avatar_url":"https://avatars.githubusercontent.com/u/709212?v=3","gravatar_id":"","url":"https://api.github.com/users/Comcast","html_url":"https://github.com/Comcast","followers_url":"https://api.github.com/users/Comcast/followers","following_url":"https://api.github.com/users/Comcast/following{/other_user}","gists_url":"https://api.github.com/users/Comcast/gists{/gist_id}","starred_url":"https://api.github.com/users/Comcast/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Comcast/subscriptions","organizations_url":"https://api.github.com/users/Comcast/orgs","repos_url":"https://api.github.com/users/Comcast/repos","events_url":"https://api.github.com/users/Comcast/events{/privacy}","received_events_url":"https://api.github.com/users/Comcast/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Comcast/jrugged","description":"A Java libary of robustness design patterns","fork":false,"url":"https://api.github.com/repos/Comcast/jrugged","forks_url":"https://api.github.com/repos/Comcast/jrugged/forks","keys_url":"https://api.github.com/repos/Comcast/jrugged/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Comcast/jrugged/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Comcast/jrugged/teams","hooks_url":"https://api.github.com/repos/Comcast/jrugged/hooks","issue_events_url":"https://api.github.com/repos/Comcast/jrugged/issues/events{/number}","events_url":"https://api.github.com/repos/Comcast/jrugged/events","assignees_url":"https://api.github.com/repos/Comcast/jrugged/assignees{/user}","branches_url":"https://api.github.com/repos/Comcast/jrugged/branches{/branch}","tags_url":"https://api.github.com/repos/Comcast/jrugged/tags","blobs_url":"https://api.github.com/repos/Comcast/jrugged/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Comcast/jrugged/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Comcast/jrugged/git/refs{/sha}","trees_url":"https://api.github.com/repos/Comcast/jrugged/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Comcast/jrugged/statuses/{sha}","languages_url":"https://api.github.com/repos/Comcast/jrugged/languages","stargazers_url":"https://api.github.com/repos/Comcast/jrugged/stargazers","contributors_url":"https://api.github.com/repos/Comcast/jrugged/contributors","subscribers_url":"https://api.github.com/repos/Comcast/jrugged/subscribers","subscription_url":"https://api.github.com/repos/Comcast/jrugged/subscription","commits_url":"https://api.github.com/repos/Comcast/jrugged/commits{/sha}","git_commits_url":"https://api.github.com/repos/Comcast/jrugged/git/commits{/sha}","comments_url":"https://api.github.com/repos/Comcast/jrugged/comments{/number}","issue_comment_url":"https://api.github.com/repos/Comcast/jrugged/issues/comments{/number}","contents_url":"https://api.github.com/repos/Comcast/jrugged/contents/{+path}","compare_url":"https://api.github.com/repos/Comcast/jrugged/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Comcast/jrugged/merges","archive_url":"https://api.github.com/repos/Comcast/jrugged/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Comcast/jrugged/downloads","issues_url":"https://api.github.com/repos/Comcast/jrugged/issues{/number}","pulls_url":"https://api.github.com/repos/Comcast/jrugged/pulls{/number}","milestones_url":"https://api.github.com/repos/Comcast/jrugged/milestones{/number}","notifications_url":"https://api.github.com/repos/Comcast/jrugged/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Comcast/jrugged/labels{/name}","releases_url":"https://api.github.com/repos/Comcast/jrugged/releases{/id}","deployments_url":"https://api.github.com/repos/Comcast/jrugged/deployments","created_at":"2012-11-08T20:28:33Z","updated_at":"2016-01-20T01:28:36Z","pushed_at":"2015-12-17T18:01:52Z","git_url":"git://github.com/Comcast/jrugged.git","ssh_url":"git@github.com:Comcast/jrugged.git","clone_url":"https://github.com/Comcast/jrugged.git","svn_url":"https://github.com/Comcast/jrugged","homepage":null,"size":2428,"stargazers_count":115,"watchers_count":115,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":42,"mirror_url":null,"open_issues_count":9,"forks":42,"open_issues":9,"watchers":115,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Comcast/jrugged/pulls/43"},"html":{"href":"https://github.com/Comcast/jrugged/pull/43"},"issue":{"href":"https://api.github.com/repos/Comcast/jrugged/issues/43"},"comments":{"href":"https://api.github.com/repos/Comcast/jrugged/issues/43/comments"},"review_comments":{"href":"https://api.github.com/repos/Comcast/jrugged/pulls/43/comments"},"review_comment":{"href":"https://api.github.com/repos/Comcast/jrugged/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Comcast/jrugged/pulls/43/commits"},"statuses":{"href":"https://api.github.com/repos/Comcast/jrugged/statuses/2da3cb21b74057c1ea748ed293037d19f3e2eb0d"}}}}