Skip to content
This repository has been archived by the owner on Nov 18, 2022. It is now read-only.

Commit

Permalink
#351: sleep longer in feed coordintator
Browse files Browse the repository at this point in the history
up to 60 seconds.
  • Loading branch information
hugbug committed Jan 26, 2019
1 parent bdc7ba3 commit 855f3e8
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 11 deletions.
46 changes: 37 additions & 9 deletions daemon/feed/FeedCoordinator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 67,9 @@ FeedCoordinator::FeedCoordinator()

m_downloadQueueObserver.m_owner = this;
DownloadQueue::Guard()->Attach(&m_downloadQueueObserver);

m_workStateObserver.m_owner = this;
g_WorkState->Attach(&m_workStateObserver);
}

FeedCoordinator::~FeedCoordinator()
Expand Down Expand Up @@ -130,7 133,7 @@ void FeedCoordinator::Run()
CheckSaveFeeds();
ResetHangingDownloads();

if (abs(Util::CurrentTime() - lastCleanup) >= 60)
if (std::abs(Util::CurrentTime() - lastCleanup) >= 60)
{
// clean up feed history once a minute
CleanupHistory();
Expand All @@ -139,8 142,25 @@ void FeedCoordinator::Run()
lastCleanup = Util::CurrentTime();
}

Guard guard(m_waitMutex);
m_waitCond.WaitFor(m_waitMutex, 1000, [&]{ return IsStopped(); });
Guard guard(m_downloadsMutex);
if (m_force)
{
// don't sleep too long if there active feeds scheduled for redownload
m_waitCond.WaitFor(m_downloadsMutex, 1000, [&]{ return IsStopped(); });
}
else
{
// no active jobs, we can sleep longer:
// - if option "UrlForce" is active or if the feed list is empty we need to wake up
// only when a new feed preview is requested. We could wait indefinitely for that
// but we need to do some job every now and then and therefore we sleep only 60 seconds.
// - if option "UrlForce" is disabled we need also to wake up when state "DownloadPaused"
// is changed. We detect this via notification from 'WorkState'. However such
// notifications are not 100% reliable due to possible race conditions. Therefore
// we sleep for max. 5 seconds.
int waitInterval = g_Options->GetUrlForce() || m_feeds.empty() ? 60000 : 5000;
m_waitCond.WaitFor(m_downloadsMutex, waitInterval, [&]{ return m_force || IsStopped(); });
}
}

// waiting for downloads
Expand All @@ -166,17 186,20 @@ void FeedCoordinator::Stop()
Thread::Stop();

debug("Stopping UrlDownloads");
Guard guard(m_downloadsMutex);
for (FeedDownloader* feedDownloader : m_activeDownloads)
{
Guard guard(m_downloadsMutex);
for (FeedDownloader* feedDownloader : m_activeDownloads)
{
feedDownloader->Stop();
}
feedDownloader->Stop();
}
debug("UrlDownloads are notified");

// Resume Run() to exit it
Guard guard(m_waitMutex);
m_waitCond.NotifyAll();
}

void FeedCoordinator::WorkStateUpdate(Subject* caller, void* aspect)
{
m_force = true;
m_waitCond.NotifyAll();
}

Expand Down Expand Up @@ -520,6 543,9 @@ std::shared_ptr<FeedItemList> FeedCoordinator::PreviewFeed(int id,
}

StartFeedDownload(feedInfo.get(), true);

m_force = true;
m_waitCond.NotifyAll();
}

// wait until the download in a separate thread completes
Expand Down Expand Up @@ -584,6 610,8 @@ void FeedCoordinator::FetchFeed(int id)
m_force = true;
}
}

m_waitCond.NotifyAll();
}

std::unique_ptr<FeedFile> FeedCoordinator::parseFeed(FeedInfo* feedInfo)
Expand Down
13 changes: 11 additions & 2 deletions daemon/feed/FeedCoordinator.h
Original file line number Diff line number Diff line change
@@ -1,7 1,7 @@
/*
* This file is part of nzbget. See <http://nzbget.net>.
*
* Copyright (C) 2013-2016 Andrey Prygunkov <[email protected]>
* Copyright (C) 2013-2019 Andrey Prygunkov <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -67,6 67,13 @@ class FeedCoordinator : public Thread, public Observer, public Subject, public D
virtual void Update(Subject* caller, void* aspect) { m_owner->DownloadQueueUpdate(caller, aspect); }
};

class WorkStateObserver: public Observer
{
public:
FeedCoordinator* m_owner;
virtual void Update(Subject* caller, void* aspect) { m_owner->WorkStateUpdate(caller, aspect); }
};

class FeedCacheItem
{
public:
Expand Down Expand Up @@ -106,11 113,12 @@ class FeedCoordinator : public Thread, public Observer, public Subject, public D
FeedHistory m_feedHistory;
Mutex m_downloadsMutex;
DownloadQueueObserver m_downloadQueueObserver;
WorkStateObserver m_workStateObserver;
bool m_force = false;
bool m_save = false;
FeedCache m_feedCache;
Mutex m_waitMutex;
ConditionVar m_waitCond;
bool m_wokenUp = false;

void StartFeedDownload(FeedInfo* feedInfo, bool force);
void FeedCompleted(FeedDownloader* feedDownloader);
Expand All @@ -124,6 132,7 @@ class FeedCoordinator : public Thread, public Observer, public Subject, public D
void CheckSaveFeeds();
std::unique_ptr<FeedFile> parseFeed(FeedInfo* feedInfo);
void SchedulerNextUpdate(FeedInfo* feedInfo, bool success);
void WorkStateUpdate(Subject* caller, void* aspect);
};

extern FeedCoordinator* g_FeedCoordinator;
Expand Down

0 comments on commit 855f3e8

Please sign in to comment.