{"action":"created","issue":{"url":"https://api.github.com/repos/javaslang/javaslang/issues/293","labels_url":"https://api.github.com/repos/javaslang/javaslang/issues/293/labels{/name}","comments_url":"https://api.github.com/repos/javaslang/javaslang/issues/293/comments","events_url":"https://api.github.com/repos/javaslang/javaslang/issues/293/events","html_url":"https://github.com/javaslang/javaslang/issues/293","id":84784210,"number":293,"title":"Add retry functionality to Try","user":{"login":"danieldietrich","id":743833,"avatar_url":"https://avatars.githubusercontent.com/u/743833?v=3","gravatar_id":"","url":"https://api.github.com/users/danieldietrich","html_url":"https://github.com/danieldietrich","followers_url":"https://api.github.com/users/danieldietrich/followers","following_url":"https://api.github.com/users/danieldietrich/following{/other_user}","gists_url":"https://api.github.com/users/danieldietrich/gists{/gist_id}","starred_url":"https://api.github.com/users/danieldietrich/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/danieldietrich/subscriptions","organizations_url":"https://api.github.com/users/danieldietrich/orgs","repos_url":"https://api.github.com/users/danieldietrich/repos","events_url":"https://api.github.com/users/danieldietrich/events{/privacy}","received_events_url":"https://api.github.com/users/danieldietrich/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/javaslang/javaslang/labels/feature","name":"feature","color":"009800"}],"state":"closed","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/javaslang/javaslang/milestones/18","html_url":"https://github.com/javaslang/javaslang/milestones/1.3.0","labels_url":"https://api.github.com/repos/javaslang/javaslang/milestones/18/labels","id":1091674,"number":18,"title":"1.3.0","description":"","creator":{"login":"danieldietrich","id":743833,"avatar_url":"https://avatars.githubusercontent.com/u/743833?v=3","gravatar_id":"","url":"https://api.github.com/users/danieldietrich","html_url":"https://github.com/danieldietrich","followers_url":"https://api.github.com/users/danieldietrich/followers","following_url":"https://api.github.com/users/danieldietrich/following{/other_user}","gists_url":"https://api.github.com/users/danieldietrich/gists{/gist_id}","starred_url":"https://api.github.com/users/danieldietrich/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/danieldietrich/subscriptions","organizations_url":"https://api.github.com/users/danieldietrich/orgs","repos_url":"https://api.github.com/users/danieldietrich/repos","events_url":"https://api.github.com/users/danieldietrich/events{/privacy}","received_events_url":"https://api.github.com/users/danieldietrich/received_events","type":"User","site_admin":false},"open_issues":21,"closed_issues":22,"state":"open","created_at":"2015-04-30T20:29:59Z","updated_at":"2015-06-04T10:02:40Z","due_on":null,"closed_at":null},"comments":10,"created_at":"2015-06-03T21:43:58Z","updated_at":"2015-06-04T13:44:16Z","closed_at":"2015-06-04T10:02:40Z","body":"@RobWin had the idea to extend `Try` with a retry functionality, s.th. like\r\n\r\n```java\r\nTry.of(Retry.of(3,supplier)).onFailure(x -> { println(\"whoops\"); }).get()\r\n```\r\n\r\nwhich will execute `onFailure` at most once, regardless how often the supplier is _retried_.\r\n\r\nThis is a great Idea. In general the exception handling can be augmented this way with additional functionality. Examples:\r\n\r\n```java\r\nTry.of(CircuitBreaker.of(Retry.of(3, supplier))).get();\r\nTry.of(Metrics.of(supplier)).get();\r\n// etc.\r\n```\r\n\r\nThe remaining question is how to integrate `Retry` without blowing up the number of classes too much.\r\n\r\nOne solution is to add a static `retry` method to `CheckedSupplier` and `CheckedRunnable`, i.e.\r\n\r\n```java\r\ninterface CheckedSupplier<T> {\r\n\r\n    T get() throws Throwable;\r\n\r\n    /**\r\n     * Tries {@code supplier.get()} n times before throwing.\r\n     */\r\n    static <T> CheckedSupplier<T> retry(int n, CheckedSupplier<T> supplier) {\r\n        if (n < 1) {\r\n            throw new IllegalArgumentException(\"n < 1\");\r\n        }\r\n        Objects.requireNonNull(supplier, \"supplier is null\");\r\n        return () -> {\r\n            for (int i = 1; i <= n; i++) {\r\n                try {\r\n                    return supplier.get();\r\n                } catch(Throwable x) {\r\n                    if (Cause.isFatal(x) || i == n) {\r\n                        throw x;\r\n                    }\r\n                }\r\n            }\r\n            // we will never get here - another line not covered by unit tests\r\n            return null;\r\n        };\r\n    }\r\n}\r\n```\r\n\r\nBtw. the `Cause.of(x).isFatal()` should be changed to `Cause.isFatal(x)`. This saves intermediate object creation."},"comment":{"url":"https://api.github.com/repos/javaslang/javaslang/issues/comments/108902955","html_url":"https://github.com/javaslang/javaslang/issues/293#issuecomment-108902955","issue_url":"https://api.github.com/repos/javaslang/javaslang/issues/293","id":108902955,"user":{"login":"RobWin","id":5815046,"avatar_url":"https://avatars.githubusercontent.com/u/5815046?v=3","gravatar_id":"","url":"https://api.github.com/users/RobWin","html_url":"https://github.com/RobWin","followers_url":"https://api.github.com/users/RobWin/followers","following_url":"https://api.github.com/users/RobWin/following{/other_user}","gists_url":"https://api.github.com/users/RobWin/gists{/gist_id}","starred_url":"https://api.github.com/users/RobWin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RobWin/subscriptions","organizations_url":"https://api.github.com/users/RobWin/orgs","repos_url":"https://api.github.com/users/RobWin/repos","events_url":"https://api.github.com/users/RobWin/events{/privacy}","received_events_url":"https://api.github.com/users/RobWin/received_events","type":"User","site_admin":false},"created_at":"2015-06-04T13:44:16Z","updated_at":"2015-06-04T13:44:16Z","body":"The signature for a more complex retry logic could be: Retry.of(supplier, retryConfig) so that the config is extendable."}}