Skip to content
Permalink
Browse files
[WK2] ResourceLoadStatistics should batch its writes
https://bugs.webkit.org/show_bug.cgi?id=174111
<rdar://problem/33115894>

Reviewed by Chris Dumez.

Revise the data writing operation to only write on a specific interval (currently
set to 5 minutes).

Also make 'writeStoreToDisk' simpler to use by moving the deleting (before write) and
creating (after write) of the FileMonitor into the method, rather than requiring this
knowledge in multiple places.

Make sure that we write our statistics file out before exiting so that we do not
lose any data if we exit before the five-minute window has elapsed.

* UIProcess/Storage/ResourceLoadStatisticsStore.cpp:
(WebKit::ResourceLoadStatisticsStore::setWritePersistentStoreCallback): Deleted.
* UIProcess/WebResourceLoadStatisticsStore.cpp:
(WebKit::WebResourceLoadStatisticsStore::processStatisticsAndDataRecords): Remove the stop
and start monitoring into 'writeStoreToDisk'. Also check if enough time has elapsed since
the last write to commit to disk.
(WebKit::WebResourceLoadStatisticsStore::registerSharedResourceLoadObserver): Remove the
stop and start monitoring into 'writeStoreToDisk'.
(WebKit::WebResourceLoadStatisticsStore::writeStoreToDisk): Add the stop and start monitoring
commands here, so callers don't have to know to do so.


Canonical link: https://commits.webkit.org/191063@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@219220 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
brentfulgham committed Jul 6, 2017
1 parent 49927a8 commit b1282e8d895e0c3fc9662aac5a9a3e5caa7ac14c
@@ -1,3 +1,32 @@
2017-07-06 Brent Fulgham <bfulgham@apple.com>

[WK2] ResourceLoadStatistics should batch its writes
https://bugs.webkit.org/show_bug.cgi?id=174111
<rdar://problem/33115894>

Reviewed by Chris Dumez.

Revise the data writing operation to only write on a specific interval (currently
set to 5 minutes).

Also make 'writeStoreToDisk' simpler to use by moving the deleting (before write) and
creating (after write) of the FileMonitor into the method, rather than requiring this
knowledge in multiple places.

Make sure that we write our statistics file out before exiting so that we do not
lose any data if we exit before the five-minute window has elapsed.

* UIProcess/Storage/ResourceLoadStatisticsStore.cpp:
(WebKit::ResourceLoadStatisticsStore::setWritePersistentStoreCallback): Deleted.
* UIProcess/WebResourceLoadStatisticsStore.cpp:
(WebKit::WebResourceLoadStatisticsStore::processStatisticsAndDataRecords): Remove the stop
and start monitoring into 'writeStoreToDisk'. Also check if enough time has elapsed since
the last write to commit to disk.
(WebKit::WebResourceLoadStatisticsStore::registerSharedResourceLoadObserver): Remove the
stop and start monitoring into 'writeStoreToDisk'.
(WebKit::WebResourceLoadStatisticsStore::writeStoreToDisk): Add the stop and start monitoring
commands here, so callers don't have to know to do so.

2017-07-06 Chris Dumez <cdumez@apple.com>

FileMonitor should not be ref counted
@@ -176,11 +176,6 @@ void ResourceLoadStatisticsStore::setShouldPartitionCookiesCallback(WTF::Functio
m_shouldPartitionCookiesForDomainsHandler = WTFMove(handler);
}

void ResourceLoadStatisticsStore::setWritePersistentStoreCallback(WTF::Function<void()>&& handler)
{
m_writePersistentStoreHandler = WTFMove(handler);
}

void ResourceLoadStatisticsStore::setGrandfatherExistingWebsiteDataCallback(WTF::Function<void()>&& handler)
{
m_grandfatherExistingWebsiteDataHandler = WTFMove(handler);
@@ -74,7 +74,6 @@ class ResourceLoadStatisticsStore : public ThreadSafeRefCounted<ResourceLoadStat

void setNotificationCallback(WTF::Function<void()>&&);
void setShouldPartitionCookiesCallback(WTF::Function<void(const Vector<String>& domainsToRemove, const Vector<String>& domainsToAdd, bool clearFirst)>&&);
void setWritePersistentStoreCallback(WTF::Function<void()>&&);
void setDeletePersistentStoreCallback(WTF::Function<void()>&&);
void setGrandfatherExistingWebsiteDataCallback(WTF::Function<void()>&&);
void setFireTelemetryCallback(WTF::Function<void()>&& handler);
@@ -107,7 +106,6 @@ class ResourceLoadStatisticsStore : public ThreadSafeRefCounted<ResourceLoadStat

WTF::Function<void()> m_dataAddedHandler;
WTF::Function<void(const Vector<String>&, const Vector<String>&, bool clearFirst)> m_shouldPartitionCookiesForDomainsHandler;
WTF::Function<void()> m_writePersistentStoreHandler;
WTF::Function<void()> m_grandfatherExistingWebsiteDataHandler;
WTF::Function<void()> m_deletePersistentStoreHandler;
WTF::Function<void()> m_fireTelemetryHandler;
@@ -40,6 +40,7 @@
#include <wtf/CrossThreadCopier.h>
#include <wtf/MainThread.h>
#include <wtf/MathExtras.h>
#include <wtf/MonotonicTime.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/RunLoop.h>
#include <wtf/Seconds.h>
@@ -59,6 +60,8 @@ template<typename T> static inline String primaryDomain(const T& value)
return ResourceLoadStatistics::primaryDomain(value);
}

constexpr Seconds minimumStatisticsFileWriteInterval { 5_min };

static bool notifyPagesWhenDataRecordsWereScanned = false;
static bool shouldClassifyResourcesBeforeDataRecordsRemoval = true;
static auto shouldSubmitTelemetry = true;
@@ -105,13 +108,6 @@ WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore(const String& res
return;
processStatisticsAndDataRecords();
});
m_resourceLoadStatisticsStore->setWritePersistentStoreCallback([this, protectedThis = makeRef(*this)] {
m_statisticsQueue->dispatch([this, protectedThis = protectedThis.copyRef()] {
stopMonitoringStatisticsStorage();
writeStoreToDisk();
startMonitoringStatisticsStorage();
});
});
m_resourceLoadStatisticsStore->setGrandfatherExistingWebsiteDataCallback([this, protectedThis = makeRef(*this)] {
grandfatherExistingWebsiteData();
});
@@ -205,11 +201,7 @@ void WebResourceLoadStatisticsStore::processStatisticsAndDataRecords()
});
}

stopMonitoringStatisticsStorage();

writeStoreToDisk();

startMonitoringStatisticsStorage();
scheduleOrWriteStoreToDisk();
});
}

@@ -319,7 +311,11 @@ void WebResourceLoadStatisticsStore::processDidCloseConnection(WebProcessProxy&,
void WebResourceLoadStatisticsStore::applicationWillTerminate()
{
BinarySemaphore semaphore;
m_statisticsQueue->dispatch([&semaphore] {
m_statisticsQueue->dispatch([&semaphore, this, protectedThis = makeRef(*this)] {
// Write final file state to disk.
if (m_didScheduleWrite)
writeStoreToDisk();

// Make sure any ongoing work in our queue is finished before we terminate.
semaphore.signal();
});
@@ -345,6 +341,8 @@ void WebResourceLoadStatisticsStore::writeStoreToDisk()
{
ASSERT(!RunLoop::isMain());

stopMonitoringStatisticsStorage();

syncWithExistingStatisticsStorageIfNeeded();

auto encoder = coreStore().createEncoderFromData();
@@ -353,6 +351,29 @@ void WebResourceLoadStatisticsStore::writeStoreToDisk()
writeEncoderToDisk(*encoder.get(), resourceLog);

m_lastStatisticsFileSyncTime = WallTime::now();
m_lastStatisticsWriteTime = MonotonicTime::now();

startMonitoringStatisticsStorage();
m_didScheduleWrite = false;
}

void WebResourceLoadStatisticsStore::scheduleOrWriteStoreToDisk()
{
ASSERT(!RunLoop::isMain());

auto timeSinceLastWrite = MonotonicTime::now() - m_lastStatisticsWriteTime;
if (timeSinceLastWrite < minimumStatisticsFileWriteInterval) {
if (!m_didScheduleWrite) {
m_didScheduleWrite = true;
Seconds delayUntil = minimumStatisticsFileWriteInterval - timeSinceLastWrite + 1_s;
m_statisticsQueue->dispatchAfter(delayUntil, [this, protectedThis = makeRef(*this)] {
writeStoreToDisk();
});
}
return;
}

writeStoreToDisk();
}

static PlatformFileHandle openAndLockFile(const String& path, FileOpenMode mode)
@@ -40,14 +40,15 @@
#endif

namespace WTF {
class MonotonicTime;
class WallTime;
class WorkQueue;
}

namespace WebCore {
class FileMonitor;
class KeyedDecoder;
class KeyedEncoder;
class FileMonitor;
struct ResourceLoadStatistics;
}

@@ -122,6 +123,7 @@ class WebResourceLoadStatisticsStore final : public IPC::Connection::WorkQueueMe
void grandfatherExistingWebsiteData();

void writeStoreToDisk();
void scheduleOrWriteStoreToDisk();
void writeEncoderToDisk(WebCore::KeyedEncoder&, const String& path) const;
std::unique_ptr<WebCore::KeyedDecoder> createDecoderFromDisk(const String& path) const;
WallTime statisticsFileModificationTime(const String& label) const;
@@ -148,8 +150,10 @@ class WebResourceLoadStatisticsStore final : public IPC::Connection::WorkQueueMe
std::unique_ptr<WebCore::FileMonitor> m_statisticsStorageMonitor;
const String m_statisticsStoragePath;
WTF::WallTime m_lastStatisticsFileSyncTime;
WTF::MonotonicTime m_lastStatisticsWriteTime;
RunLoop::Timer<WebResourceLoadStatisticsStore> m_telemetryOneShotTimer;
RunLoop::Timer<WebResourceLoadStatisticsStore> m_telemetryRepeatedTimer;
bool m_didScheduleWrite { false };
};

} // namespace WebKit

0 comments on commit b1282e8

Please sign in to comment.