private ConstraintContext createConstraintContext(Job job, long checkTime) { // should be fine to pass in null as the Store parameter, since its not used in this test return new ConstraintContext(job, checkTime, null); }
private ConstraintResult notSatisfied(ConstraintContext context) { if (!waitUntilMet) { return ConstraintResult.NEVER_SATISFIED; } return new ConstraintResult(ConstraintResult.SatisfiedState.NOT_SATISFIED, context.getCheckTimeMillis() + TimeUnit.SECONDS.toMillis(10)); } }
@Override public ConstraintResult check(ProgramSchedule schedule, ConstraintContext context) { long elapsedTime = context.getCheckTimeMillis() - context.getJob().getCreationTime(); if (elapsedTime >= millisAfterTrigger) { return ConstraintResult.SATISFIED; } return new ConstraintResult(ConstraintResult.SatisfiedState.NOT_SATISFIED, context.getJob().getCreationTime() + millisAfterTrigger); } }
@Override public ConstraintResult check(ProgramSchedule schedule, ConstraintContext context) { long startTime = TimeUnit.MILLISECONDS.toSeconds(context.getCheckTimeMillis() - millisSinceLastRun); // We only need to check program runs within recent history, adding a buffer of 1 day, because the time range // is for the start time of the program. It may start before `millisSinceLastRun`, but complete after it. // Note: this will miss out on active workflow runs that started more than ~1day ago (suspended/lengthy workflows) Iterable<RunRecordMeta> runRecords = context.getProgramRuns(schedule.getProgramId(), ProgramRunStatus.ALL, startTime - TimeUnit.DAYS.toSeconds(1), Long.MAX_VALUE, 100).values(); // We can limit to 100, since just 1 program in the recent history is enough to make the constraint fail. // We want use 100 as the limit instead of 1, because we want to attempt to get the latest completed run, // instead of just the first (in order to more accurately compute a next runtime if (Iterables.isEmpty(filter(runRecords, startTime))) { return ConstraintResult.SATISFIED; } if (!waitUntilMet) { return ConstraintResult.NEVER_SATISFIED; } return new ConstraintResult(ConstraintResult.SatisfiedState.NOT_SATISFIED, context.getCheckTimeMillis() + TimeUnit.SECONDS.toMillis(10)); }
@Test public void testDelayConstraint() { long now = System.currentTimeMillis(); ProgramSchedule schedule = new ProgramSchedule("SCHED1", "one partition schedule", WORKFLOW_ID, ImmutableMap.of("prop3", "abc"), new PartitionTrigger(DATASET_ID, 1), ImmutableList.<Constraint>of()); SimpleJob job = new SimpleJob(schedule, now, Collections.<Notification>emptyList(), Job.State.PENDING_TRIGGER, 0L); // test with 10 minute delay DelayConstraint tenMinuteDelayConstraint = new DelayConstraint(10, TimeUnit.MINUTES); // a check against 12 minutes after 'now' will return SATISFIED ConstraintContext constraintContext = new ConstraintContext(job, now + TimeUnit.MINUTES.toMillis(12), null); ConstraintResult result = tenMinuteDelayConstraint.check(schedule, constraintContext); Assert.assertEquals(ConstraintResult.SATISFIED, result); // a check against 9 minutes after 'now' will return NOT_SATISFIED, with 1 minute to wait until next retry constraintContext = new ConstraintContext(job, now + TimeUnit.MINUTES.toMillis(9), null); result = tenMinuteDelayConstraint.check(schedule, constraintContext); Assert.assertEquals(ConstraintResult.SatisfiedState.NOT_SATISFIED, result.getSatisfiedState()); Assert.assertEquals(constraintContext.getCheckTimeMillis() + TimeUnit.MINUTES.toMillis(1), (long) result.getNextCheckTime()); }
@Override public ConstraintResult check(ProgramSchedule schedule, ConstraintContext context) { int numRunning = context.getProgramRuns(schedule.getProgramId(), ProgramRunStatus.RUNNING, maxConcurrency).size(); if (numRunning >= maxConcurrency) { LOG.debug("Skipping run of program {} from schedule {} because there are at least {} running runs.", schedule.getProgramId(), schedule.getName(), maxConcurrency); return notSatisfied(context); } int numSuspended = context.getProgramRuns(schedule.getProgramId(), ProgramRunStatus.SUSPENDED, maxConcurrency).size(); if (numRunning + numSuspended >= maxConcurrency) { LOG.debug("Skipping run of program {} from schedule {} because there are at least" + "{} running runs and at least {} suspended runs.", schedule.getProgramId(), schedule.getName(), numRunning, numSuspended); return notSatisfied(context); } return ConstraintResult.SATISFIED; }
@Override public ConstraintResult check(ProgramSchedule schedule, ConstraintContext context) { long startTime = TimeUnit.MILLISECONDS.toSeconds(context.getCheckTimeMillis() - millisSinceLastRun); // We only need to check program runs within recent history, adding a buffer of 1 day, because the time range // is for the start time of the program. It may start before `millisSinceLastRun`, but complete after it. // Note: this will miss out on active workflow runs that started more than ~1day ago (suspended/lengthy workflows) Iterable<RunRecordMeta> runRecords = context.getProgramRuns(schedule.getProgramId(), ProgramRunStatus.ALL, startTime - TimeUnit.DAYS.toSeconds(1), Long.MAX_VALUE, 100).values(); // We can limit to 100, since just 1 program in the recent history is enough to make the constraint fail. // We want use 100 as the limit instead of 1, because we want to attempt to get the latest completed run, // instead of just the first (in order to more accurately compute a next runtime if (Iterables.isEmpty(filter(runRecords, startTime))) { return ConstraintResult.SATISFIED; } if (!waitUntilMet) { return ConstraintResult.NEVER_SATISFIED; } return new ConstraintResult(ConstraintResult.SatisfiedState.NOT_SATISFIED, context.getCheckTimeMillis() + TimeUnit.SECONDS.toMillis(10)); }
@Override public ConstraintResult check(ProgramSchedule schedule, ConstraintContext context) { int numRunning = context.getProgramRuns(schedule.getProgramId(), ProgramRunStatus.RUNNING, maxConcurrency).size(); if (numRunning >= maxConcurrency) { LOG.debug("Skipping run of program {} from schedule {} because there are at least {} running runs.", schedule.getProgramId(), schedule.getName(), maxConcurrency); return notSatisfied(context); } int numSuspended = context.getProgramRuns(schedule.getProgramId(), ProgramRunStatus.SUSPENDED, maxConcurrency).size(); if (numRunning + numSuspended >= maxConcurrency) { LOG.debug("Skipping run of program {} from schedule {} because there are at least" + "{} running runs and at least {} suspended runs.", schedule.getProgramId(), schedule.getName(), numRunning, numSuspended); return notSatisfied(context); } return ConstraintResult.SATISFIED; }
private ConstraintResult notSatisfied(ConstraintContext context) { if (!waitUntilMet) { return ConstraintResult.NEVER_SATISFIED; } return new ConstraintResult(ConstraintResult.SatisfiedState.NOT_SATISFIED, context.getCheckTimeMillis() + TimeUnit.SECONDS.toMillis(10)); } }
private ConstraintResult.SatisfiedState constraintsSatisfied(Job job, long now) { ConstraintResult.SatisfiedState satisfiedState = ConstraintResult.SatisfiedState.SATISFIED; ConstraintContext constraintContext = new ConstraintContext(job, now, store); for (Constraint constraint : job.getSchedule().getConstraints()) { if (!(constraint instanceof CheckableConstraint)) { // this shouldn't happen, since implementation of Constraint in ProgramSchedule // should implement CheckableConstraint throw new IllegalArgumentException("Implementation of Constraint in ProgramSchedule" + " must implement CheckableConstraint"); } CheckableConstraint abstractConstraint = (CheckableConstraint) constraint; ConstraintResult result = abstractConstraint.check(job.getSchedule(), constraintContext); if (result.getSatisfiedState() == ConstraintResult.NEVER_SATISFIED.getSatisfiedState()) { // if any of the constraints are NEVER_SATISFIED, return NEVER_SATISFIED return ConstraintResult.NEVER_SATISFIED.getSatisfiedState(); } if (result.getSatisfiedState() == ConstraintResult.SatisfiedState.NOT_SATISFIED) { satisfiedState = ConstraintResult.SatisfiedState.NOT_SATISFIED; } } return satisfiedState; }
@Override public ConstraintResult check(ProgramSchedule schedule, ConstraintContext context) { long elapsedTime = context.getCheckTimeMillis() - context.getJob().getCreationTime(); if (elapsedTime >= millisAfterTrigger) { return ConstraintResult.SATISFIED; } return new ConstraintResult(ConstraintResult.SatisfiedState.NOT_SATISFIED, context.getJob().getCreationTime() + millisAfterTrigger); } }
@Override public ConstraintResult check(ProgramSchedule schedule, ConstraintContext context) { initialize(); calendar.setTimeInMillis(context.getCheckTimeMillis()); int hourOfDay = calendar.get(Calendar.HOUR_OF_DAY); int minute = calendar.get(Calendar.MINUTE);
private ConstraintResult.SatisfiedState constraintsSatisfied(Job job, long now) { ConstraintResult.SatisfiedState satisfiedState = ConstraintResult.SatisfiedState.SATISFIED; ConstraintContext constraintContext = new ConstraintContext(job, now, store); for (Constraint constraint : job.getSchedule().getConstraints()) { if (!(constraint instanceof CheckableConstraint)) { // this shouldn't happen, since implementation of Constraint in ProgramSchedule // should implement CheckableConstraint throw new IllegalArgumentException("Implementation of Constraint in ProgramSchedule" + " must implement CheckableConstraint"); } CheckableConstraint abstractConstraint = (CheckableConstraint) constraint; ConstraintResult result = abstractConstraint.check(job.getSchedule(), constraintContext); if (result.getSatisfiedState() == ConstraintResult.NEVER_SATISFIED.getSatisfiedState()) { // if any of the constraints are NEVER_SATISFIED, return NEVER_SATISFIED return ConstraintResult.NEVER_SATISFIED.getSatisfiedState(); } if (result.getSatisfiedState() == ConstraintResult.SatisfiedState.NOT_SATISFIED) { satisfiedState = ConstraintResult.SatisfiedState.NOT_SATISFIED; } } return satisfiedState; }
@Override public ConstraintResult check(ProgramSchedule schedule, ConstraintContext context) { initialize(); calendar.setTimeInMillis(context.getCheckTimeMillis()); int hourOfDay = calendar.get(Calendar.HOUR_OF_DAY); int minute = calendar.get(Calendar.MINUTE);
ConstraintContext constraintContext = new ConstraintContext(job, now, store);
@Test public void testForwardRange() { // 3:24PM PST long now = 1494368640000L; SimpleJob job = new SimpleJob(SCHEDULE, now, Collections.<Notification>emptyList(), Job.State.PENDING_TRIGGER, 0L); // use a TimeRangeConstraint [4:00PM, 5:00PM) TimeRangeConstraint timeRangeConstraint = new TimeRangeConstraint("16:00", "17:00", TimeZone.getTimeZone("PST")); ConstraintContext constraintContext = createConstraintContext(job, now); ConstraintResult result = timeRangeConstraint.check(SCHEDULE, constraintContext); Assert.assertEquals(ConstraintResult.SatisfiedState.NOT_SATISFIED, result.getSatisfiedState()); // 36 minutes till 4PM Assert.assertEquals(constraintContext.getCheckTimeMillis() + TimeUnit.MINUTES.toMillis(36), (long) result.getNextCheckTime()); constraintContext = createConstraintContext(job, result.getNextCheckTime() - 1); result = timeRangeConstraint.check(SCHEDULE, constraintContext); Assert.assertEquals(ConstraintResult.SatisfiedState.NOT_SATISFIED, result.getSatisfiedState()); Assert.assertEquals(constraintContext.getCheckTimeMillis() + 1L, (long) result.getNextCheckTime()); result = timeRangeConstraint.check(SCHEDULE, createConstraintContext(job, now + TimeUnit.MINUTES.toMillis(36))); Assert.assertEquals(ConstraintResult.SATISFIED, result); // 5:00PM PST long fivePM = 1494374400000L; constraintContext = createConstraintContext(job, fivePM); result = timeRangeConstraint.check(SCHEDULE, constraintContext); Assert.assertEquals(ConstraintResult.SatisfiedState.NOT_SATISFIED, result.getSatisfiedState()); // 23 hours until the next time its 4PM again Assert.assertEquals(constraintContext.getCheckTimeMillis() + TimeUnit.HOURS.toMillis(23), (long) result.getNextCheckTime()); }
ConstraintContext constraintContext = new ConstraintContext(job, now, store);
Assert.assertEquals(constraintContext.getCheckTimeMillis() + sixHoursAnd36Minutes, (long) result.getNextCheckTime()); result = timeRangeConstraint.check(SCHEDULE, constraintContext); Assert.assertEquals(ConstraintResult.SatisfiedState.NOT_SATISFIED, result.getSatisfiedState()); Assert.assertEquals(constraintContext.getCheckTimeMillis() + 1L, (long) result.getNextCheckTime()); Assert.assertEquals(ConstraintResult.SatisfiedState.NOT_SATISFIED, result.getSatisfiedState()); Assert.assertEquals(constraintContext.getCheckTimeMillis() + TimeUnit.HOURS.toMillis(5), (long) result.getNextCheckTime()); Assert.assertEquals(ConstraintResult.SatisfiedState.NOT_SATISFIED, result.getSatisfiedState()); Assert.assertEquals(constraintContext.getCheckTimeMillis() + TimeUnit.HOURS.toMillis(16), (long) result.getNextCheckTime()); Assert.assertEquals(ConstraintResult.SatisfiedState.NOT_SATISFIED, result.getSatisfiedState()); Assert.assertEquals(constraintContext.getCheckTimeMillis() + TimeUnit.HOURS.toMillis(15), (long) result.getNextCheckTime());