Skip to content
This repository has been archived by the owner on Jul 12, 2023. It is now read-only.

Add support for CRON syntax for schedules #44

Merged
merged 10 commits into from
Mar 28, 2017
Merged

Add support for CRON syntax for schedules #44

merged 10 commits into from
Mar 28, 2017

Conversation

rouzwawi
Copy link
Member

@rouzwawi rouzwawi commented Jan 24, 2017

todo:

  • Parse CRON syntax for Partitioning
  • Backwards compatible with previous Partitioning enum values
  • Add offset field supporting ISO 8601 Durations for offsetting trigger time
  • Align Workflow Instance parameter generation for general CRON Partitioning
  • Persist offset trigger time (for API)
  • Workflow Instance parameter parsing in Scheduler trigger API
  • Documentation
  • Lower interval limit (pushed for later PR)

fixes #37

@luster
Copy link

luster commented Mar 20, 2017

is there a release timeline for this feature? @rouzwawi

@danielnorberg
Copy link
Contributor

danielnorberg commented Mar 21, 2017

Does this mean that a workflow can be scheduled to run once a minute?

@rouzwawi
Copy link
Member Author

@danielnorberg yes. I was thinking of adding a lower limit on the schedule interval. Running a new pod every minute can definitely cause issues.

@rouzwawi
Copy link
Member Author

@luster We're looking into merging this soon. Rough guess would around a week from now.

@rouzwawi rouzwawi force-pushed the cron branch 6 times, most recently from 2a05a2d to ba81f4a Compare March 22, 2017 18:59
@danielnorberg
Copy link
Contributor

Would it be relevant to consider the smearing issue in this PR as well?

#110

@rouzwawi rouzwawi force-pushed the cron branch 2 times, most recently from c8bd435 to e8917d3 Compare March 24, 2017 21:54
@rouzwawi
Copy link
Member Author

@danielnorberg I would prefer to do it in a separate PR, as I don't think it should be implemented on the triggering layer. See my comment in the issue.

}

@Override
public Map<Workflow, Optional<Instant>> workflowsWithNextNaturalTrigger()
throws IOException {
public void updateNextNaturalTriggerOld(WorkflowId workflowId, Instant instant) throws IOException {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems this method is not used anywhere. Still keeping it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's used from a test that simulates the storage condition before migrating to this. Will add a VisibleForTesting annotation.

throws IOException {
Map<Workflow, Optional<Instant>> map = Maps.newHashMap();
public Map<Workflow, TriggerInstantSpec> workflowsWithNextNaturalTrigger() throws IOException {
Map<Workflow, TriggerInstantSpec> map = Maps.newHashMap();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

final


map.put(workflow, TriggerInstantSpec.create(instant, triggerInstant));
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

empty line

@@ -265,16 +286,31 @@ public void updateNextNaturalTrigger(WorkflowId workflowId, Instant nextNaturalT
final Entity entity = result.next();
Workflow workflow;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

final

Instant instant = datetimeToInstant(entity.getDateTime(PROPERTY_NEXT_NATURAL_TRIGGER));
Instant triggerInstant;

// todo: this check is only needed during a transition period
Copy link
Member

@honnix honnix Mar 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you like to perform a data migration by adding a new property now? Or let it migrate itself when updating natural trigger?


if (entity.contains(PROPERTY_NEXT_NATURAL_TRIGGER)) {
Instant instant = datetimeToInstant(entity.getDateTime(PROPERTY_NEXT_NATURAL_TRIGGER));
Instant triggerInstant;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

final


private ParameterUtil() {
}

private static final int MIN_YEAR_WIDTH = 4;
private static final int MAX_YEAR_WIDTH = 10;

private static final DateTimeFormatter DATE_HOUR_FORMAT = new DateTimeFormatterBuilder()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This stack alike builder is not quite readable. Hopefully we will never need to change it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😱

@@ -153,18 +153,18 @@ public void setUp() throws Exception {
storage.storeWorkflow(Workflow.create(
BACKFILL_1.workflowId().componentId(), URI.create("http://example.com"),
WorkflowConfiguration.create(BACKFILL_1.workflowId().id(), Schedule.HOURS,
Optional.empty(), Optional.empty(), Optional.empty(),
Optional.empty(), Collections.emptyList())));
empty(), empty(), empty(), empty(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an argument for using builders somewhere in these lines ;)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes :) I wonder if there's a good library for that ;)

}

public enum WellKnown {
HOURLY, DAILY, WEEKLY, MONTHLY, YEARLY, UNKNOWN
Copy link
Contributor

@danielnorberg danielnorberg Mar 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WellKnown.UNKNOWN 😄

final Schedule.WellKnown wellKnown = schedule.wellKnown();

Matcher matcher;
ZonedDateTime parsed;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

final

previous = storage.workflow(workflow.id());
storage.storeWorkflow(workflow);
} catch (IOException e) {
throw Throwables.propagate(e);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@danielnorberg found this https://github.com/google/guava/wiki/Why-we-deprecated-Throwables.propagate, so I would suggest for new code we don't use propagate.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good read. I had started questioning the usefulness of Throwables.propagate.

}

@Deprecated
public void updateNextNaturalTrigger(WorkflowId workflowId, Instant instant) throws IOException {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here. Do you still need this method?


final Consumer<Workflow> workflowChangeListener = workflowChanged(workflowCache, storage,
stats, stateManager, time);
final WorkflowInitializer workflowInitializer = new WorkflowInitializer(storage, time);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inline this maybe as it's only used by workflowChangeListener? or move it closer to where it is used.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would just push down more of the dependencies (storage, time) into the workflowChanged handler which does not use them at the moment. So it's a net +1 dependency. I'll keep it here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't mean that change. Just

final Consumer<Workflow> workflowChangeListener =
        workflowChanged(workflowCache, new WorkflowInitializer(storage, time), stats, stateManager);

But it's OK.

@honnix
Copy link
Member

honnix commented Mar 28, 2017

A few minor comments.

public abstract Instant instant();

/**
* The actual instant at which the Workflow will be instantiated, with respect to the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/instantiated/triggered ?

@danielnorberg
Copy link
Contributor

LGTM overall 👍

@rouzwawi
Copy link
Member Author

@honnix @danielnorberg Fixed review comments

@rouzwawi rouzwawi merged commit cad991b into master Mar 28, 2017
@rouzwawi rouzwawi deleted the cron branch March 28, 2017 15:29
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support CRON syntax for Workflow schedules
4 participants