@Test public void testScheduleIsIdempotent() throws Exception { JobRequest request = DummyJobs.createBuilder(DummyJobs.SuccessJob.class) .setExecutionWindow(300_000, 400_000) .build(); int jobId = request.schedule(); long scheduledAt = request.getScheduledAt(); assertThat(scheduledAt).isGreaterThan(0L); Thread.sleep(10); int newJobId = request.schedule(); assertThat(newJobId).isEqualTo(jobId); assertThat(request.getScheduledAt()).isEqualTo(scheduledAt); }
public synchronized void schedule(@NonNull JobRequest request) { if (mJobCreatorHolder.isEmpty()) { CAT.w("you haven't registered a JobCreator with addJobCreator(), it's likely that your job never will be executed"); } if (request.getScheduledAt() > 0) { return; } if (request.isUpdateCurrent()) { cancelAllForTag(request.getTag()); } JobProxy.Common.cleanUpOrphanedJob(mContext, request.getJobId()); JobApi jobApi = request.getJobApi(); boolean periodic = request.isPeriodic(); boolean flexSupport = periodic && jobApi.isFlexSupport() && request.getFlexMs() < request.getIntervalMs(); request.setScheduledAt(JobConfig.getClock().currentTimeMillis()); request.setFlexSupport(flexSupport); getJobStorage().put(request); try { scheduleWithApi(request, jobApi, periodic, flexSupport); return; } catch (JobProxyIllegalStateException e) { } catch (Exception e) { getJobStorage().remove(request); throw e; } try { jobApi.invalidateCachedProxy(); scheduleWithApi(request, jobApi, periodic, flexSupport); return; } catch (Exception e) { if (jobApi == JobApi.V_14 || jobApi == JobApi.V_19) { getJobStorage().remove(request); throw e; } else { jobApi = JobApi.V_19.isSupported(mContext) ? JobApi.V_19 : JobApi.V_14; } } try { scheduleWithApi(request, jobApi, periodic, flexSupport); } catch (Exception e) { getJobStorage().remove(request); throw e; } }
JobManager { public synchronized void schedule(@NonNull JobRequest request) { if (mJobCreatorHolder.isEmpty()) { CAT.w("you haven't registered a JobCreator with addJobCreator(), it's likely that your job never will be executed"); } if (request.getScheduledAt() > 0) { return; } if (request.isUpdateCurrent()) { cancelAllForTag(request.getTag()); } JobProxy.Common.cleanUpOrphanedJob(mContext, request.getJobId()); JobApi jobApi = request.getJobApi(); boolean periodic = request.isPeriodic(); boolean flexSupport = periodic && jobApi.isFlexSupport() && request.getFlexMs() < request.getIntervalMs(); request.setScheduledAt(JobConfig.getClock().currentTimeMillis()); request.setFlexSupport(flexSupport); getJobStorage().put(request); try { scheduleWithApi(request, jobApi, periodic, flexSupport); return; } catch (JobProxyIllegalStateException e) { } catch (Exception e) { getJobStorage().remove(request); throw e; } try { jobApi.invalidateCachedProxy(); scheduleWithApi(request, jobApi, periodic, flexSupport); return; } catch (Exception e) { if (jobApi == JobApi.V_14 || jobApi == JobApi.V_19) { getJobStorage().remove(request); throw e; } else { jobApi = JobApi.V_19.isSupported(mContext) ? JobApi.V_19 : JobApi.V_14; } } try { scheduleWithApi(request, jobApi, periodic, flexSupport); } catch (Exception e) { getJobStorage().remove(request); throw e; } } }
JobManager { public synchronized void schedule(@NonNull JobRequest request) { if (mJobCreatorHolder.isEmpty()) { CAT.w("you haven't registered a JobCreator with addJobCreator(), it's likely that your job never will be executed"); } if (request.getScheduledAt() > 0) { return; } if (request.isUpdateCurrent()) { cancelAllForTag(request.getTag()); } JobProxy.Common.cleanUpOrphanedJob(mContext, request.getJobId()); JobApi jobApi = request.getJobApi(); boolean periodic = request.isPeriodic(); boolean flexSupport = periodic && jobApi.isFlexSupport() && request.getFlexMs() < request.getIntervalMs(); request.setScheduledAt(JobConfig.getClock().currentTimeMillis()); request.setFlexSupport(flexSupport); getJobStorage().put(request); try { scheduleWithApi(request, jobApi, periodic, flexSupport); return; } catch (JobProxyIllegalStateException e) { } catch (Exception e) { getJobStorage().remove(request); throw e; } try { jobApi.invalidateCachedProxy(); scheduleWithApi(request, jobApi, periodic, flexSupport); return; } catch (Exception e) { if (jobApi == JobApi.V_14 || jobApi == JobApi.V_19) { getJobStorage().remove(request); throw e; } else { jobApi = JobApi.V_19.isSupported(mContext) ? JobApi.V_19 : JobApi.V_14; } } try { scheduleWithApi(request, jobApi, periodic, flexSupport); } catch (Exception e) { getJobStorage().remove(request); throw e; } } private  JobManager(final Context context); }
JobManager { public synchronized void schedule(@NonNull JobRequest request) { if (mJobCreatorHolder.isEmpty()) { CAT.w("you haven't registered a JobCreator with addJobCreator(), it's likely that your job never will be executed"); } if (request.getScheduledAt() > 0) { return; } if (request.isUpdateCurrent()) { cancelAllForTag(request.getTag()); } JobProxy.Common.cleanUpOrphanedJob(mContext, request.getJobId()); JobApi jobApi = request.getJobApi(); boolean periodic = request.isPeriodic(); boolean flexSupport = periodic && jobApi.isFlexSupport() && request.getFlexMs() < request.getIntervalMs(); request.setScheduledAt(JobConfig.getClock().currentTimeMillis()); request.setFlexSupport(flexSupport); getJobStorage().put(request); try { scheduleWithApi(request, jobApi, periodic, flexSupport); return; } catch (JobProxyIllegalStateException e) { } catch (Exception e) { getJobStorage().remove(request); throw e; } try { jobApi.invalidateCachedProxy(); scheduleWithApi(request, jobApi, periodic, flexSupport); return; } catch (Exception e) { if (jobApi == JobApi.V_14 || jobApi == JobApi.V_19) { getJobStorage().remove(request); throw e; } else { jobApi = JobApi.V_19.isSupported(mContext) ? JobApi.V_19 : JobApi.V_14; } } try { scheduleWithApi(request, jobApi, periodic, flexSupport); } catch (Exception e) { getJobStorage().remove(request); throw e; } } private  JobManager(final Context context); static JobManager create(@NonNull Context context); static JobManager instance(); synchronized void schedule(@NonNull JobRequest request); JobRequest getJobRequest(int jobId); @NonNull Set<JobRequest> getAllJobRequests(); Set<JobRequest> getAllJobRequestsForTag(@NonNull String tag); Job getJob(int jobId); @NonNull Set<Job> getAllJobs(); @NonNull Set<Job> getAllJobsForTag(@NonNull String tag); @NonNull SparseArray<Job.Result> getAllJobResults(); boolean cancel(int jobId); int cancelAll(); int cancelAllForTag(@NonNull String tag); void addJobCreator(JobCreator jobCreator); void removeJobCreator(JobCreator jobCreator); }
JobManager { public synchronized void schedule(@NonNull JobRequest request) { if (mJobCreatorHolder.isEmpty()) { CAT.w("you haven't registered a JobCreator with addJobCreator(), it's likely that your job never will be executed"); } if (request.getScheduledAt() > 0) { return; } if (request.isUpdateCurrent()) { cancelAllForTag(request.getTag()); } JobProxy.Common.cleanUpOrphanedJob(mContext, request.getJobId()); JobApi jobApi = request.getJobApi(); boolean periodic = request.isPeriodic(); boolean flexSupport = periodic && jobApi.isFlexSupport() && request.getFlexMs() < request.getIntervalMs(); request.setScheduledAt(JobConfig.getClock().currentTimeMillis()); request.setFlexSupport(flexSupport); getJobStorage().put(request); try { scheduleWithApi(request, jobApi, periodic, flexSupport); return; } catch (JobProxyIllegalStateException e) { } catch (Exception e) { getJobStorage().remove(request); throw e; } try { jobApi.invalidateCachedProxy(); scheduleWithApi(request, jobApi, periodic, flexSupport); return; } catch (Exception e) { if (jobApi == JobApi.V_14 || jobApi == JobApi.V_19) { getJobStorage().remove(request); throw e; } else { jobApi = JobApi.V_19.isSupported(mContext) ? JobApi.V_19 : JobApi.V_14; } } try { scheduleWithApi(request, jobApi, periodic, flexSupport); } catch (Exception e) { getJobStorage().remove(request); throw e; } } private  JobManager(final Context context); static JobManager create(@NonNull Context context); static JobManager instance(); synchronized void schedule(@NonNull JobRequest request); JobRequest getJobRequest(int jobId); @NonNull Set<JobRequest> getAllJobRequests(); Set<JobRequest> getAllJobRequestsForTag(@NonNull String tag); Job getJob(int jobId); @NonNull Set<Job> getAllJobs(); @NonNull Set<Job> getAllJobsForTag(@NonNull String tag); @NonNull SparseArray<Job.Result> getAllJobResults(); boolean cancel(int jobId); int cancelAll(); int cancelAllForTag(@NonNull String tag); void addJobCreator(JobCreator jobCreator); void removeJobCreator(JobCreator jobCreator);  }