Activity auto-deletion/"easy idempotence" in Procedural Scheduling
Opened this issue · 2 comments
Background
Proposed new feature for the Java Procedural Scheduling library.
Procedural scheduling goals are essentially Java programs that can make arbitrary changes to the Plan, such as adding, editing or removing activities. This was an intentional decision to maximize their expressiveness - however, since Aerie provides no guarantees or restrictions on how goals will behave or what kind of "side effects" they have, they may end up having behavior which is tied to the number of times they have been run. For example, if a goal simply adds an activity to the plan every time it runs, then you'll get a new activity every time you run the goal, with a total number of activities = number of runs.
This kind of situation can be hard to reason about, and cause unpredictable results, so generally we recommend that users try to make their activities idempotent, that is, to have their side effects be independent of how many times they were run. Running 10 times should produce the same result as once. However, we can't guarantee idempotence of goals in general because some important use cases and performance optimizations may rely on intentional non-idempotence.
Description
The proposal from @JoelCourtney (and echoed in requests from users) is to provide a method in the scheduling library which allows users to guarantee that their goals will be idempotent by automatically cleaning up the activities they create. Specifically:
- We should add a function call or different class to inherit from to the Procedural Scheduling API
guarantee_idempotence()
?clean_up_activities()
? or maybeIdempotentGoal
? open to suggestions
- The user can use this function/class in their goal to intentionally opt-in if desired
- When the goal is run, we first look for any activity directives in the plan that were placed by a previous invocation of the same goal, and delete them.
- If the plan goal specification contains multiple invocations of the same goal (ie. with different parameters), this deletion should only apply to activities created by the previous run of the same invocation, rather than all activities created by the goal in all of its invocations.
- Then run the goal as usual, adding any new activities to the plan
Extra Credit
Something to think about when implementing this feature - this addresses "cleaning up" activities from past runs before the next run, but what if a user decides a goal invocation is no longer relevant, and removes it from the plan spec entirely - the activities it created will remain, with no easy way to delete them all (if desired). Maybe we should also think about an option to "remove activities created by this goal invocation" when removing a goal from a plan?
This sounds like a fantastic idea. I would vote for a simple function like clean_up_activities()
with simple to understand English as opposed to using the term idempotent
, which may not be familiar to new users. I also like the extra credit, especially if it is as simple as a quick dialog upon deletion of a goal from a plan that gives you one last opportunity to clean up activities produced by the goal if so desired.
@ewferg Yeah I was planning on something like deletePreviousResults
or deletePreviousActivities
I like the "extra credit" idea too, but I think that would probably be a UI thing, not a scheduling thing.