Never Timing not evaluating correctly

Tony Sheehy 12 years ago updated by anonymous 8 years ago 22

A get all entities timing configuration of the following, will not evaluate and blocks access to the home page.

        <Timing id="5793f282-2d8a-4fa8-8f9c-2f055334087c" name="DailyExclusion" useLocal="true">
            <ExclusionPeriod daysExclusionApplies="Monday,Tuesday,Wednesday,Thursday,Friday,Saturday" start="00:00:00" end="23:59:59" />
          <Timing id="66f8c661-8535-405f-ad53-5a17299b5030" name="DayExclusion" daysToExclude="Sunday,Monday,Tuesday,Wednesday,Thursday,Friday" useLocal="true">
            <Timing id="3280577b-fe63-405c-986e-d1d02f26ed0a" name="RecurringTimespanStandardTime" useLocal="true" startFrom="2012-05-21T14:00:11">
              <Timespan value="00:00:30" />

Matthew, I recall that this issue was covered during EB development. Can you please take a look?

This eventually resolves, but it takes far too long to do so. The result should be cached, and/or it should not be allowed to run years into the future before determining it will never run.

I thought that there was a limit of how long it would spend trying to calculate.

For beta take a look at the unit tests around this scenario.


Assigned to Tony to confirm as to why this is taking so long

I've just tested this locally and could not reproduce.

Tony, did you debug a timing that runs frequently, that is completely blacked out, as it was checking if it was due?

I checked with the same config, (twice with the tail/head days of the two exclusion periods incremented/decremented) on a 30 second recurring timespan.

I didn't debug it, but I could navigate to the homepage and it correctly defined the time as 'Never'.

This eventually resolves, but it takes far too long to do so. The result should be cached, and/or it should not be allowed to run years into the future before determining it will never run.

Resolved as discussed, the evaluation time is not enough to spend the time on caching the results.

This has not been fixed.

Whilst testing locally, a timing took about 1 minute to resolve as never. And took that long every time the home page was visited, as well as perform operations against that connector.

Of note, a timespan of 3h evaluates substantially faster than a 30 second timespan.

An initial attempt at fixes has been pushed to a separate branch. It currently doesn't work, but the idea for how to fix this issue is there.

Currently, essentially the problem is that whether the current time is in the exclusion period is calculated every increment, between "now" and the end of the "current exclusion period". This means that smaller increments directly affect performance.

What I want to have happen is that instead, each exclusion period calculates the end of the "current" exclusion period, and then increments to that end, and then loops if that calculated time is in an exclusion period.

The only problem with the above is you can't just increment to the end of the exclusion period - you need to increment to the first time that falls outside of the exclusion period, which it is already doing.

If we cache the timing as a never timing until it's fixed, then you only encounter the issue once. This could be done as soon as the schedule is updated.

The other option is to prevent it from running so far ahead that it times out after several years - perhaps the schedules can only be set to run as far as 1 year into the future before declaring something will never run?

You can't currently, but it would be entirely possible for each exclusion timing to calculate the end of an exclusion period from a provided time, and then you just increment from the current time to that end. What this would do is cut down on the processing per increment, as the calculation would happen once, as opposed to per increment.

If it's determined that this work is going to be too lengthy and/or difficult to get right, we can push it to v4.1.

The fix version for this issue has been updated to v4.1. The individual changes might not be too large/difficult, but they do change to core logic of each timing decorator, and would be too risky just before RC1.

The algorithm involves using CalculateNextRunAfterTime and passing in the end of the exclusion to that method, rather than the current approach of incrementing, checking the next run after the incremented time, incrementing again etc.

Moved to 4.2 based on remaining estimate.

How-To fix this:

Currently execution works by this:

+ Add time
? Check whether current time falls under exclusion

This means that for each N where n is the number of iterations of Add time, you're executing a potentially expensive operation.

Alternative, is have the expensive operations say when they finish:

var state = When does the exclusion end
+ Add time
? Is current time after state

The difference is that the second conditional is just a timestamp.compare versus the expensive operation.

Can't see how the solution would work. What time would be added after the exclusion? It's not the interval of the timing, because that would only work if the exclusion could be divided by a whole number of time periods.

Reassigned following discussion of solution.

Migrated to VSO.