RESOLVED FIXED 174235
[WK2] Use a rolling 30-day uptime for processing statistics
https://bugs.webkit.org/show_bug.cgi?id=174235
Summary [WK2] Use a rolling 30-day uptime for processing statistics
Brent Fulgham
Reported 2017-07-06 20:43:38 PDT
Switch from using a 30-day calendar date to a rolling set of 30 uptime events before processing load statistics.
Attachments
Patch (7.13 KB, patch)
2017-07-06 20:52 PDT, Brent Fulgham
no flags
Patch (8.29 KB, patch)
2017-07-07 12:32 PDT, Brent Fulgham
no flags
Patch (9.64 KB, patch)
2017-07-07 14:04 PDT, Brent Fulgham
no flags
Patch (11.74 KB, patch)
2017-07-07 14:30 PDT, Brent Fulgham
no flags
Patch (11.87 KB, patch)
2017-07-07 14:46 PDT, Brent Fulgham
no flags
Patch (11.90 KB, patch)
2017-07-07 15:17 PDT, Brent Fulgham
no flags
Patch (13.38 KB, patch)
2017-07-07 16:00 PDT, Brent Fulgham
no flags
Follow-up fix (6.39 KB, patch)
2017-07-07 21:24 PDT, Chris Dumez
no flags
Brent Fulgham
Comment 1 2017-07-06 20:44:07 PDT
Brent Fulgham
Comment 2 2017-07-06 20:52:31 PDT
Brent Fulgham
Comment 3 2017-07-06 20:53:21 PDT
Using EWS as my build machine right now.
Brent Fulgham
Comment 4 2017-07-07 12:32:48 PDT
Chris Dumez
Comment 5 2017-07-07 13:06:56 PDT
Comment on attachment 314860 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=314860&action=review > Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.cpp:532 > +void WebResourceLoadStatisticsStore::handleDailyTasks() performDailyTasks? > Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.cpp:541 > void WebResourceLoadStatisticsStore::telemetryTimerFired() Can we rename to submitTelemetryIfNecessary() for clarity? > Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:93 > + // Running history Missing period at the end. > Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:138 > + // Running history Missing period at the end. > Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:315 > + if (doesExceedActiveWindow(resourceStatistic.mostRecentUserInteractionTime)) { Would exceedsActiveWindow() work? or hasStatisticsExpired(resourceStatistic) ? > Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:426 > +bool ResourceLoadStatisticsStore::isSameDayAsCurrentOperatingDate(const WTF::WallTime& date) const This is always called with WallTime::now() parameter. Does it really need a parameter? > Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:437 > + m_operatingDates.append(WallTime::now()); How about: while (m_operatingDates.size() >= operatingDatesWindow) m_operatingDates.removeFirst(); m_operatingDates.append(WallTime::now()); > Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:447 > +bool ResourceLoadStatisticsStore::doesExceedActiveWindow(const WTF::WallTime& date) const We do not need WTF:: prefix in the cpp. The only reason you need it in the header is because you forward declared. WallTime is a double, no need to pass by const reference, we should pass it by value everywhere. > Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:454 > + // For testing Missing period at the end. What does this do? Why is this needed for testing? > Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.h:104 > + bool doesExceedActiveWindow(const WTF::WallTime&) const; Can be private. > Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.h:105 > + bool isSameDayAsCurrentOperatingDate(const WTF::WallTime&) const; Could we move this into includeTodayAsOperatingDate(), which we would rename to includeTodayAsOperatingDateIfNecesary() ? > Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.h:114 > + Vector<WTF::WallTime> m_operatingDates; This should be a Deque, not a Vector, since you remove from the front. > Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.h:115 > + WTF::WallTime m_earliestRetainedDate; Why do we need this data member? It seems it is always m_operatingDates.first() ?
Brent Fulgham
Comment 6 2017-07-07 13:53:25 PDT
Comment on attachment 314860 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=314860&action=review >> Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.cpp:541 >> void WebResourceLoadStatisticsStore::telemetryTimerFired() > > Can we rename to submitTelemetryIfNecessary() for clarity? Done. >> Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:93 >> + // Running history > > Missing period at the end. This comment doesn't really add anything, so I'll remove it. >> Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:138 >> + // Running history > > Missing period at the end. I'll remove this comment, too. >> Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:315 >> + if (doesExceedActiveWindow(resourceStatistic.mostRecentUserInteractionTime)) { > > Would exceedsActiveWindow() work? or hasStatisticsExpired(resourceStatistic) ? I like "hasStatisticsExpired" >> Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:426 >> +bool ResourceLoadStatisticsStore::isSameDayAsCurrentOperatingDate(const WTF::WallTime& date) const > > This is always called with WallTime::now() parameter. Does it really need a parameter? I guess not! >> Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:437 >> + m_operatingDates.append(WallTime::now()); > > How about: > while (m_operatingDates.size() >= operatingDatesWindow) > m_operatingDates.removeFirst(); > m_operatingDates.append(WallTime::now()); Yes -- that's better. >> Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:447 >> +bool ResourceLoadStatisticsStore::doesExceedActiveWindow(const WTF::WallTime& date) const > > We do not need WTF:: prefix in the cpp. The only reason you need it in the header is because you forward declared. > WallTime is a double, no need to pass by const reference, we should pass it by value everywhere. Will do. >> Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:454 >> + // For testing > > Missing period at the end. What does this do? Why is this needed for testing? We can set m_timeToLiveUserInteraction to a tighter window than the default, which is helpful for triggering this during testing. >> Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.h:104 >> + bool doesExceedActiveWindow(const WTF::WallTime&) const; > > Can be private. Will do. >> Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.h:105 >> + bool isSameDayAsCurrentOperatingDate(const WTF::WallTime&) const; > > Could we move this into includeTodayAsOperatingDate(), which we would rename to includeTodayAsOperatingDateIfNecesary() ? Yes, I think that works properly. I'll make that change. >> Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.h:114 >> + Vector<WTF::WallTime> m_operatingDates; > > This should be a Deque, not a Vector, since you remove from the front. Yeah, that makes sense. I was a little lazy here and just used Vector, since it encodes/decodes without additional steps. >> Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.h:115 >> + WTF::WallTime m_earliestRetainedDate; > > Why do we need this data member? It seems it is always m_operatingDates.first() ? I thought it would be more efficient to cache this value the one time a day we change it, so that checks against it would be faster. Maybe there is no meaningful per difference with a dequeue first() dereference?
Chris Dumez
Comment 7 2017-07-07 13:55:42 PDT
Comment on attachment 314860 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=314860&action=review >>> Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:454 >>> + // For testing >> >> Missing period at the end. What does this do? Why is this needed for testing? > > We can set m_timeToLiveUserInteraction to a tighter window than the default, which is helpful for triggering this during testing. Yes, I would just include this in the comment. >>> Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.h:115 >>> + WTF::WallTime m_earliestRetainedDate; >> >> Why do we need this data member? It seems it is always m_operatingDates.first() ? > > I thought it would be more efficient to cache this value the one time a day we change it, so that checks against it would be faster. Maybe there is no meaningful per difference with a dequeue first() dereference? I wouldn't think it is worth it to optimize a Deque::first() access, although you'll need a branch to check if the Deque is empty too.
Brent Fulgham
Comment 8 2017-07-07 14:04:05 PDT
Brent Fulgham
Comment 9 2017-07-07 14:07:55 PDT
Comment on attachment 314875 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=314875&action=review > Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:44 > +const Seconds lengthOfDay { 30_s }; Whoops! This shouldn't stay like this. > Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:152 > + m_operatingDates.append(WTFMove(date)); Chris: Is there a more efficient way to populate a Deque from a Vector?
Brent Fulgham
Comment 10 2017-07-07 14:10:36 PDT
Comment on attachment 314860 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=314860&action=review >>>> Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.h:115 >>>> + WTF::WallTime m_earliestRetainedDate; >>> >>> Why do we need this data member? It seems it is always m_operatingDates.first() ? >> >> I thought it would be more efficient to cache this value the one time a day we change it, so that checks against it would be faster. Maybe there is no meaningful per difference with a dequeue first() dereference? > > I wouldn't think it is worth it to optimize a Deque::first() access, although you'll need a branch to check if the Deque is empty too. Actually, the only place I am using this is right after a size check, so it's pretty silly to bother trying to cache this value. I'll switch to m_earliestRetainedDate.first() instead and get rid of this member.
Brent Fulgham
Comment 11 2017-07-07 14:11:20 PDT
Comment on attachment 314875 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=314875&action=review > Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:445 > + if (date < m_earliestRetainedDate) I'll change this to m_earliestRetainedDate.first() > Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.h:115 > + WTF::WallTime m_earliestRetainedDate; I'll get rid of the m_earliestRetainedDate.
Chris Dumez
Comment 12 2017-07-07 14:12:38 PDT
Comment on attachment 314875 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=314875&action=review > Source/WebKit2/UIProcess/API/Cocoa/WKWebsiteDataStore.mm:443 > + store->setTimeToLiveUserInteraction(0_s); Is this intentional? Why are we doing this? Also, this needs to match the default value of the m_timeToLiveUserInteraction member in ResourceLoadStatistics. > Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:44 > +const Seconds lengthOfDay { 30_s }; lengthOfDay is 30 seconds? > Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:139 > + succeeded = decoder.decodeObjects("operatingDates", dates, [](KeyedDecoder& decoder, WallTime& wallTime) { Could we update decodeObjects() so that the second parameter is a template parameter? Its code should build for either Vector and Deque since both support append(). > Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:318 > + if (hasStatisticsExpired(resourceStatistic.mostRecentUserInteractionTime)) { Given the name I suggested, my suggestion was to take resourceStatistic in parameter, not resourceStatistic.mostRecentUserInteractionTime. > Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:434 > + if (!m_operatingDates.isEmpty() && (WallTime::now() - m_operatingDates.last() < lengthOfDay)) Should this be *before* the removal? Also, I do not know what this check is about yet. > Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:439 > + m_earliestRetainedDate = m_operatingDates.first(); Why is this still here?
Brent Fulgham
Comment 13 2017-07-07 14:30:16 PDT
Brent Fulgham
Comment 14 2017-07-07 14:31:25 PDT
Comment on attachment 314880 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=314880&action=review > Source/WebKit2/UIProcess/API/Cocoa/WKWebsiteDataStore.mm:443 > + store->setTimeToLiveUserInteraction(0_s); It seems weird to have these, if they just set the store to its defaults. Couldn't that be a method on the store, that just sets them back to defaults, rather than requiring the knowledge in two places?
Chris Dumez
Comment 15 2017-07-07 14:41:25 PDT
(In reply to Brent Fulgham from comment #14) > Comment on attachment 314880 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=314880&action=review > > > Source/WebKit2/UIProcess/API/Cocoa/WKWebsiteDataStore.mm:443 > > + store->setTimeToLiveUserInteraction(0_s); > > It seems weird to have these, if they just set the store to its defaults. > Couldn't that be a method on the store, that just sets them back to > defaults, rather than requiring the knowledge in two places? I totally agree. I just have got around to refactor this part yet. It is on my TODO list though.
Brent Fulgham
Comment 16 2017-07-07 14:46:42 PDT
Chris Dumez
Comment 17 2017-07-07 15:01:00 PDT
Comment on attachment 314882 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=314882&action=review > Source/WebCore/platform/KeyedCoding.h:130 > + bool decodeObjects(const String& key, Deque<T>& objects, F&& function) This seems like an exact copy paste of the method above. Why didn't you use a template parameter for the objects parameter type as I suggested? I think this would avoid the duplication. > Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:430 > + if (!m_operatingDates.isEmpty() && (WallTime::now() - m_operatingDates.last() < 24_h)) Shouldn't this happen before we remove? Otherwise, we'll possibly end up removing a date but not adding one.
Brent Fulgham
Comment 18 2017-07-07 15:17:27 PDT
Brent Fulgham
Comment 19 2017-07-07 15:20:31 PDT
Comment on attachment 314882 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=314882&action=review >> Source/WebCore/platform/KeyedCoding.h:130 >> + bool decodeObjects(const String& key, Deque<T>& objects, F&& function) > > This seems like an exact copy paste of the method above. Why didn't you use a template parameter for the objects parameter type as I suggested? I think this would avoid the duplication. I'm trying to get the template/template syntax right, and I didn't want to risk breaking Vector uses. I'm uploading a new patch. >> Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:430 >> + if (!m_operatingDates.isEmpty() && (WallTime::now() - m_operatingDates.last() < 24_h)) > > Shouldn't this happen before we remove? Otherwise, we'll possibly end up removing a date but not adding one. But we might enter this routine a second time during the same 24-hour period. If the m_operatingDates queue is empty, we add the current date. If it's not empty, and the dates are for the same day, then we don't want to add. I think this is correct as written.
Brent Fulgham
Comment 20 2017-07-07 15:25:39 PDT
Comment on attachment 314882 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=314882&action=review >>> Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:430 >>> + if (!m_operatingDates.isEmpty() && (WallTime::now() - m_operatingDates.last() < 24_h)) >> >> Shouldn't this happen before we remove? Otherwise, we'll possibly end up removing a date but not adding one. > > But we might enter this routine a second time during the same 24-hour period. If the m_operatingDates queue is empty, we add the current date. If it's not empty, and the dates are for the same day, then we don't want to add. > > I think this is correct as written. I mean is that it seems okay to remove dates if we are already outside the bounds of our allowed operating window. Even if the current date is the same day as the last time stamp, it's okay to throw away the dates that are outside the allowed range of 'operatingDatesWindow' count.
Brent Fulgham
Comment 21 2017-07-07 15:29:28 PDT
(In reply to Brent Fulgham from comment #20) > Comment on attachment 314882 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=314882&action=review > > >>> Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:430 > >>> + if (!m_operatingDates.isEmpty() && (WallTime::now() - m_operatingDates.last() < 24_h)) > >> > >> Shouldn't this happen before we remove? Otherwise, we'll possibly end up removing a date but not adding one. > > > > But we might enter this routine a second time during the same 24-hour period. If the m_operatingDates queue is empty, we add the current date. If it's not empty, and the dates are for the same day, then we don't want to add. > > > > I think this is correct as written. > > I mean is that it seems okay to remove dates if we are already outside the > bounds of our allowed operating window. Even if the current date is the same > day as the last time stamp, it's okay to throw away the dates that are > outside the allowed range of 'operatingDatesWindow' count. I spoke to Chris offline, and agree that we might fall below the window if we are right on the edge of a day transition.
Brent Fulgham
Comment 22 2017-07-07 16:00:55 PDT
Chris Dumez
Comment 23 2017-07-07 16:15:05 PDT
Comment on attachment 314887 [details] Patch r=me if the bots are happy.
WebKit Commit Bot
Comment 24 2017-07-07 17:07:16 PDT
Comment on attachment 314887 [details] Patch Clearing flags on attachment: 314887 Committed r219274: <http://trac.webkit.org/changeset/219274>
WebKit Commit Bot
Comment 25 2017-07-07 17:07:18 PDT
All reviewed patches have been landed. Closing bug.
Chris Dumez
Comment 26 2017-07-07 21:10:30 PDT
This caused http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction-timeout.html to time out.
Chris Dumez
Comment 27 2017-07-07 21:11:34 PDT
Comment on attachment 314887 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=314887&action=review > Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsStore.cpp:445 > + if (m_timeToLiveUserInteraction) { This is bad because the test (http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction-timeout.html) sets it to 0.
Chris Dumez
Comment 28 2017-07-07 21:14:14 PDT
Reopening because test failure needs to be addressed.
Chris Dumez
Comment 29 2017-07-07 21:24:56 PDT
Created attachment 314913 [details] Follow-up fix
Brent Fulgham
Comment 30 2017-07-07 22:06:29 PDT
Comment on attachment 314913 [details] Follow-up fix Thank you for fixing this!
Chris Dumez
Comment 31 2017-07-07 22:09:59 PDT
Comment on attachment 314913 [details] Follow-up fix Clearing flags on attachment: 314913 Committed r219275: <http://trac.webkit.org/changeset/219275>
Chris Dumez
Comment 32 2017-07-07 22:10:02 PDT
All reviewed patches have been landed. Closing bug.
Note You need to log in before you can comment on or make changes to this bug.