use of co.cask.cdap.internal.app.runtime.schedule.ProgramSchedule in project cdap by caskdata.
the class Schedulers method toProgramSchedule.
public static ProgramSchedule toProgramSchedule(ApplicationId appId, ScheduleSpecification spec) {
Schedule schedule = spec.getSchedule();
ProgramType programType = ProgramType.valueOfSchedulableType(spec.getProgram().getProgramType());
ProgramId programId = appId.program(programType, spec.getProgram().getProgramName());
Trigger trigger;
if (schedule instanceof TimeSchedule) {
TimeSchedule timeSchedule = (TimeSchedule) schedule;
trigger = new TimeTrigger(timeSchedule.getCronEntry());
} else {
StreamSizeSchedule streamSchedule = (StreamSizeSchedule) schedule;
StreamId streamId = programId.getNamespaceId().stream(streamSchedule.getStreamName());
trigger = new StreamSizeTrigger(streamId, streamSchedule.getDataTriggerMB());
}
Integer maxConcurrentRuns = schedule.getRunConstraints().getMaxConcurrentRuns();
List<Constraint> constraints = maxConcurrentRuns == null ? ImmutableList.<Constraint>of() : ImmutableList.<Constraint>of(new ConcurrencyConstraint(maxConcurrentRuns));
return new ProgramSchedule(schedule.getName(), schedule.getDescription(), programId, spec.getProperties(), trigger, constraints);
}
use of co.cask.cdap.internal.app.runtime.schedule.ProgramSchedule in project cdap by caskdata.
the class JobQueueDataset method addNotification.
@Override
public void addNotification(ProgramScheduleRecord record, Notification notification) {
boolean jobExists = false;
ProgramSchedule schedule = record.getSchedule();
try (CloseableIterator<Job> jobs = getJobsForSchedule(schedule.getScheduleId())) {
while (jobs.hasNext()) {
Job job = jobs.next();
if (job.getState() == Job.State.PENDING_TRIGGER) {
// ConstraintCheckerService
if (job.isToBeDeleted()) {
// ignore, it will be deleted by ConstraintCheckerService
continue;
}
long scheduleLastUpdated = record.getMeta().getLastUpdated();
if (job.getScheduleLastUpdatedTime() != scheduleLastUpdated) {
// schedule has changed: this job is obsolete
table.put(getRowKey(job.getJobKey().getScheduleId(), job.getJobKey().getCreationTime()), IS_OBSOLETE_COL, Bytes.toBytes(System.currentTimeMillis()));
} else if (System.currentTimeMillis() - job.getCreationTime() > job.getSchedule().getTimeoutMillis()) {
// job has timed out; mark it obsolete
table.put(getRowKey(job.getJobKey().getScheduleId(), job.getJobKey().getCreationTime()), IS_OBSOLETE_COL, Bytes.toBytes(System.currentTimeMillis()));
} else {
jobExists = true;
addNotification(job, notification);
break;
}
}
}
}
// if no job exists for the scheduleId, add a new job with the first notification
if (!jobExists) {
List<Notification> notifications = Collections.singletonList(notification);
Job.State jobState = isTriggerSatisfied(schedule.getTrigger(), notifications) ? Job.State.PENDING_CONSTRAINT : Job.State.PENDING_TRIGGER;
put(new SimpleJob(schedule, System.currentTimeMillis(), notifications, jobState, record.getMeta().getLastUpdated()));
}
}
use of co.cask.cdap.internal.app.runtime.schedule.ProgramSchedule in project cdap by caskdata.
the class ProgramScheduleStoreDataset method findSchedules.
/**
* Find all schedules that have a trigger with a given trigger key.
*
* @param triggerKey the trigger key to look up
* @return a list of all schedules that are triggered by this key; never null
*/
public Collection<ProgramScheduleRecord> findSchedules(String triggerKey) {
Map<ScheduleId, ProgramScheduleRecord> schedulesFound = new HashMap<>();
try (Scanner scanner = store.readByIndex(TRIGGER_KEY_COLUMN_BYTES, Bytes.toBytes(triggerKey))) {
Row triggerRow;
while ((triggerRow = scanner.next()) != null) {
String triggerRowKey = Bytes.toString(triggerRow.getRow());
try {
ScheduleId scheduleId = extractScheduleIdFromTriggerKey(triggerRowKey);
if (schedulesFound.containsKey(scheduleId)) {
continue;
}
Row row = store.get(new Get(rowKeyForSchedule(scheduleId)));
byte[] serialized = row.get(SCHEDULE_COLUMN_BYTES);
if (serialized == null) {
throw new NotFoundException(scheduleId);
}
ProgramSchedule schedule = GSON.fromJson(Bytes.toString(serialized), ProgramSchedule.class);
ProgramScheduleMeta meta = extractMetaFromRow(scheduleId, row);
ProgramScheduleRecord record = new ProgramScheduleRecord(schedule, meta);
schedulesFound.put(scheduleId, record);
} catch (IllegalArgumentException | NotFoundException e) {
// the only exceptions we know to be thrown here are IllegalArgumentException (ill-formed key) or
// NotFoundException (if the schedule does not exist). Both should never happen, so we warn and ignore.
// we will let any other exception propagate up, because it would be a DataSetException or similarly serious.
LOG.warn("Problem with trigger id '{}' found for trigger key '{}': {}. Skipping entry.", triggerRowKey, triggerKey, e.getMessage());
}
}
}
return schedulesFound.values();
}
use of co.cask.cdap.internal.app.runtime.schedule.ProgramSchedule in project cdap by caskdata.
the class ProgramScheduleStoreDataset method listSchedules.
/*------------------- private helpers ---------------------*/
private List<ProgramSchedule> listSchedules(ApplicationId appId, @Nullable ProgramId programId) {
List<ProgramSchedule> result = new ArrayList<>();
byte[] prefix = keyPrefixForApplicationScan(appId);
try (Scanner scanner = store.scan(new Scan(prefix, Bytes.stopKeyForPrefix(prefix)))) {
Row row;
while ((row = scanner.next()) != null) {
byte[] serialized = row.get(SCHEDULE_COLUMN_BYTES);
if (serialized != null) {
ProgramSchedule schedule = GSON.fromJson(Bytes.toString(serialized), ProgramSchedule.class);
if (programId == null || programId.equals(schedule.getProgramId())) {
result.add(schedule);
}
}
}
}
return result;
}
Aggregations