Commit 17f72bbd authored by falken's avatar falken Committed by Commit bot

Service Worker: Reset "idle" timer upon completion of an event.

Otherwise the worker could get stopped if the timer happens to expire between
events while it's in a flurry of events.

BUG=462096

Review URL: https://codereview.chromium.org/1038763005

Cr-Commit-Position: refs/heads/master@{#322341}
parent 8a132a4f
......@@ -1693,6 +1693,7 @@ template <typename IDMAP>
void ServiceWorkerVersion::RemoveCallbackAndStopIfDoomed(
IDMAP* callbacks,
int request_id) {
RestartTick(&idle_time_);
callbacks->Remove(request_id);
if (is_doomed_) {
// The stop should be already scheduled, but try to stop immediately, in
......
......@@ -302,7 +302,7 @@ class CONTENT_EXPORT ServiceWorkerVersion
friend class ServiceWorkerURLRequestJobTest;
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerControlleeRequestHandlerTest,
ActivateWaitingVersion);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, ScheduleStopWorker);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, IdleTimeout);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, KeepAlive);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, ListenerAvailability);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, SetDevToolsAttached);
......
......@@ -411,7 +411,11 @@ TEST_F(ServiceWorkerVersionTest, RepeatedlyObserveStatusChanges) {
ASSERT_EQ(ServiceWorkerVersion::REDUNDANT, statuses[4]);
}
TEST_F(ServiceWorkerVersionTest, ScheduleStopWorker) {
TEST_F(ServiceWorkerVersionTest, IdleTimeout) {
// Used to reliably test when the idle time gets reset regardless of clock
// granularity.
const base::TimeDelta kOneSecond = base::TimeDelta::FromSeconds(1);
// Verify the timer is not running when version initializes its status.
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
EXPECT_FALSE(version_->timeout_timer_.IsRunning());
......@@ -422,9 +426,13 @@ TEST_F(ServiceWorkerVersionTest, ScheduleStopWorker) {
base::RunLoop().RunUntilIdle();
EXPECT_EQ(SERVICE_WORKER_OK, status);
EXPECT_TRUE(version_->timeout_timer_.IsRunning());
EXPECT_FALSE(version_->idle_time_.is_null());
// The timer should be running if the worker is restarted without controllee.
// The idle time should be reset if the worker is restarted without
// controllee.
status = SERVICE_WORKER_ERROR_FAILED;
version_->idle_time_ -= kOneSecond;
base::TimeTicks idle_time = version_->idle_time_;
version_->StopWorker(CreateReceiverOnCurrentThread(&status));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(SERVICE_WORKER_OK, status);
......@@ -433,8 +441,11 @@ TEST_F(ServiceWorkerVersionTest, ScheduleStopWorker) {
base::RunLoop().RunUntilIdle();
EXPECT_EQ(SERVICE_WORKER_OK, status);
EXPECT_TRUE(version_->timeout_timer_.IsRunning());
EXPECT_LT(idle_time, version_->idle_time_);
// Adding controllee doesn't stop the stop-worker-timer.
// Adding a controllee resets the idle time.
version_->idle_time_ -= kOneSecond;
idle_time = version_->idle_time_;
scoped_ptr<ServiceWorkerProviderHost> host(
new ServiceWorkerProviderHost(33 /* dummy render process id */,
MSG_ROUTING_NONE /* render_frame_id */,
......@@ -444,6 +455,19 @@ TEST_F(ServiceWorkerVersionTest, ScheduleStopWorker) {
NULL));
version_->AddControllee(host.get());
EXPECT_TRUE(version_->timeout_timer_.IsRunning());
EXPECT_LT(idle_time, version_->idle_time_);
// Completing an event resets the idle time.
status = SERVICE_WORKER_ERROR_FAILED;
version_->idle_time_ -= kOneSecond;
idle_time = version_->idle_time_;
version_->DispatchFetchEvent(ServiceWorkerFetchRequest(),
base::Bind(&base::DoNothing),
base::Bind(&ReceiveFetchResult, &status));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(SERVICE_WORKER_OK, status);
EXPECT_LT(idle_time, version_->idle_time_);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment