-
Notifications
You must be signed in to change notification settings - Fork 94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix.all xtriggers on an itask are the same #5791
Fix.all xtriggers on an itask are the same #5791
Conversation
239893e
to
e751dcb
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess we had (wrongly) assumed a task would only ever have one clock trigger, so cache to avoid doing the datetime computation every time the trigger is checked.
With multiple clock triggers, it might still be worth caching all the values?
I have done this, although I'm not sure how much time the memoization saves. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
65fed81
to
a99576c
Compare
all clock triggers being the same.
a99576c
to
fbc4c89
Compare
if offset_str is None: | ||
trigger_time = self.point | ||
# None cannot be used as a dict key: | ||
offset_str = offset_str if offset_str else 'P0Y' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could avoid this line by just storing None
in the clock_trigger_times
dict?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, although I've never tried using None
as a dictionary key before, and was somewhat surprised by it as a thing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a bit more complex in practice - because if offset_str
is in self.clock_trigger_times
it makes the following logic invalid and you have to write a separate loop caching the conversion of P0Y
into seconds since epoch. I ended up with this diff:
- # None cannot be used as a dict key:
- offset_str = offset_str if offset_str else 'P0Y'
- if offset_str not in self.clock_trigger_times:
- if offset_str == 'P0Y':
- trigger_time = point
- else:
- trigger_time = point + ISO8601Interval(offset_str)
-
+ trigger_time = None
+ if (
+ offset_str is None
+ and self.clock_trigger_times[offset_str] == 'P0Y'
+ ):
+ trigger_time = point
+ elif offset_str not in self.clock_trigger_times:
+ trigger_time = point + ISO8601Interval(offset_str)
+ if trigger_time:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None
is hashable so can be used as a dict key
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None
is hashable so can be used as a dict key
Yes. TIL - still doesn't deal with the other problem.
Removed the plain wrong comment about using None as a dictionary key.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a bit more complex in practice - because if
offset_str
is inself.clock_trigger_times
it makes the following logic invalid and you have to write a separate loop caching the conversion ofP0Y
into seconds since epoch. I ended up with this diff:
I'm not sure what you mean by this. What I am suggesting is:
diff --git a/cylc/flow/task_proxy.py b/cylc/flow/task_proxy.py
index ac1ec5c1c..1fcd91b71 100644
--- a/cylc/flow/task_proxy.py
+++ b/cylc/flow/task_proxy.py
@@ -248,5 +248,5 @@ class TaskProxy:
self.non_unique_events = Counter() # type: ignore # TODO: figure out
- self.clock_trigger_times: Dict[str, int] = {}
+ self.clock_trigger_times: Dict[Optional[str], int] = {}
self.expire_time: Optional[float] = None
self.late_time: Optional[float] = None
@@ -370,15 +370,13 @@ class TaskProxy:
"""
- # None cannot be used as a dict key:
- offset_str = offset_str if offset_str else 'P0Y'
if offset_str not in self.clock_trigger_times:
- if offset_str == 'P0Y':
+ if not offset_str:
trigger_time = point
else:
trigger_time = point + ISO8601Interval(offset_str)
- offset = int(
- point_parse(str(trigger_time)).seconds_since_unix_epoch)
- self.clock_trigger_times[offset_str] = offset
+ self.clock_trigger_times[offset_str] = int(
+ point_parse(str(trigger_time)).seconds_since_unix_epoch
+ )
return self.clock_trigger_times[offset_str]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Too late - Oliver's merged it! - And yes, I had misunderstood.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Leaving umerged while @MetRonnie 's comments are open.
Co-authored-by: Ronnie Dutta <61982285+MetRonnie@users.noreply.github.com>
Closes #5783
The task proxy object was caching the value of clock trigger time. Only the first xtrigger was checked!
Check List
CONTRIBUTING.md
and added my name as a Code Contributor.setup.cfg
(andconda-environment.yml
if present).CHANGES.md
entry included if this is a change that can affect users?.?.x
branch.