{"action":"opened","issue":{"url":"https://api.github.com/repos/google/guava/issues/1982","labels_url":"https://api.github.com/repos/google/guava/issues/1982/labels{/name}","comments_url":"https://api.github.com/repos/google/guava/issues/1982/comments","events_url":"https://api.github.com/repos/google/guava/issues/1982/events","html_url":"https://github.com/google/guava/issues/1982","id":59239258,"number":1982,"title":"AbstractScheduledService.Scheduler.newFixedDelaySchedule & AbstractScheduledService.Scheduler.newFixedRateSchedule should fail fast","user":{"login":"fror","id":666970,"avatar_url":"https://avatars.githubusercontent.com/u/666970?v=3","gravatar_id":"","url":"https://api.github.com/users/fror","html_url":"https://github.com/fror","followers_url":"https://api.github.com/users/fror/followers","following_url":"https://api.github.com/users/fror/following{/other_user}","gists_url":"https://api.github.com/users/fror/gists{/gist_id}","starred_url":"https://api.github.com/users/fror/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fror/subscriptions","organizations_url":"https://api.github.com/users/fror/orgs","repos_url":"https://api.github.com/users/fror/repos","events_url":"https://api.github.com/users/fror/events{/privacy}","received_events_url":"https://api.github.com/users/fror/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2015-02-27T13:59:44Z","updated_at":"2015-02-27T13:59:44Z","closed_at":null,"body":"Creating a Scheduler using the two existing factory methods doesn't fail fast as I've had this example of stack trace where I was extremely surprised to see none of my classes.\r\n\r\n```\r\njava.lang.IllegalArgumentException\r\n\tat java.util.concurrent.ScheduledThreadPoolExecutor.scheduleWithFixedDelay(ScheduledThreadPoolExecutor.java:589)\r\n\tat java.util.concurrent.Executors$DelegatedScheduledExecutorService.scheduleWithFixedDelay(Executors.java:738)\r\n\tat com.google.common.util.concurrent.WrappingScheduledExecutorService.scheduleWithFixedDelay(WrappingScheduledExecutorService.java:59)\r\n\tat com.google.common.util.concurrent.AbstractScheduledService$Scheduler$1.schedule(AbstractScheduledService.java:127)\r\n\tat com.google.common.util.concurrent.AbstractScheduledService$1$3.run(AbstractScheduledService.java:201)\r\n\tat com.google.common.util.concurrent.Callables$3.run(Callables.java:95)\r\n\tat java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)\r\n\tat java.util.concurrent.FutureTask.run(FutureTask.java:266)\r\n\tat java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)\r\n\tat java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)\r\n\tat java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)\r\n\tat java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)\r\n\tat java.lang.Thread.run(Thread.java:745)\r\n```\r\n\r\nSo please add a quick fail to those factory methods so people can properly understand what exactly is going on and why it fails. \r\n\r\nMore comprehensively, the two factory methods should fail fast despite mentioning the  `ScheduledExecutorService.scheduleAtXxxxxRate(java.lang.Runnable, long, long, java.util.concurrent.TimeUnit)` note. I guess they should at least throw IllegalArgumentException like the delegated method does.\r\n\r\nHere is the code I used to find the issue and which left me pondering this for a long time.\r\n```javascript\r\npublic class AbstractScheduledServiceFastFailTest {\r\n    @Test public void test() {\r\n        class MyService extends AbstractScheduledService {\r\n            int iteration = 1;\r\n            @Override protected void runOneIteration() { iteration++; }\r\n            @Override protected Scheduler scheduler() {\r\n                return Scheduler.newFixedDelaySchedule(0, 0, TimeUnit.MILLISECONDS);\r\n            }\r\n        }\r\n        MyService service = new MyService();\r\n        service.addListener(new Service.Listener() {\r\n            @Override\r\n            public void failed(Service.State from, Throwable failure) {\r\n                failure.printStackTrace(System.err);\r\n            }\r\n        }, MoreExecutors.directExecutor());\r\n        service.startAsync();\r\n        try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { }\r\n        Assert.assertNotEquals(1, service.iteration);\r\n        service.stopAsync();\r\n    }\r\n}\r\n```"}}