Don't queue live story requests. (#641)

This commit is contained in:
dosiecki 2014-12-29 15:18:52 -08:00
parent 1d4c1556e3
commit ec5762f6d2
2 changed files with 66 additions and 59 deletions

View file

@ -73,13 +73,12 @@ public class Main extends NbActivity implements StateChangedListener, SwipeRefre
protected void onResume() {
super.onResume();
// clear the read-this-session flag from stories so they don't show up in the wrong place
NBSyncService.clearPendingStoryRequest();
NBSyncService.setActivationMode(NBSyncService.ActivationMode.ALL);
FeedUtils.activateAllStories();
FeedUtils.clearReadingSession();
updateStatusIndicators();
// this view doesn't show stories, it is safe to alter stories
FeedUtils.activateAllStories();
NBSyncService.setActivationMode(NBSyncService.ActivationMode.ALL);
triggerSync();
if (PrefsUtils.isLightThemeSelected(this) != isLightTheme) {

View file

@ -67,6 +67,7 @@ public class NBSyncService extends Service {
public enum ActivationMode { ALL, OLDER, NEWER };
private static final Object WAKELOCK_MUTEX = new Object();
private static final Object PENDING_FEED_MUTEX = new Object();
private volatile static boolean ActionsRunning = false;
private volatile static boolean CleanupRunning = false;
@ -87,9 +88,10 @@ public class NBSyncService extends Service {
private static long lastFeedCount = 0L;
private static long lastFFWriteMillis = 0L;
/** Feed sets that we need to sync and how many stories the UI wants for them. */
private static Map<FeedSet,Integer> PendingFeeds;
static { PendingFeeds = new HashMap<FeedSet,Integer>(); }
/** Feed set that we need to sync immediately for the UI. */
private static FeedSet PendingFeed;
private static Integer PendingFeedTarget = 0;
/** Feed sets that the API has said to have no more pages left. */
private static Set<FeedSet> ExhaustedFeeds;
static { ExhaustedFeeds = new HashSet<FeedSet>(); }
@ -195,7 +197,7 @@ public class NBSyncService extends Service {
syncActions();
// these requests are expressly enqueued by the UI/user, do them next
syncPendingFeeds();
syncPendingFeedStories();
syncMetadata(startId);
@ -415,56 +417,54 @@ public class NBSyncService extends Service {
/**
* Fetch stories needed because the user is actively viewing a feed or folder.
*/
private void syncPendingFeeds() {
private void syncPendingFeedStories() {
FeedSet fs = PendingFeed;
if (fs == null) return;
try {
Set<FeedSet> handledFeeds = new HashSet<FeedSet>();
feedloop: for (FeedSet fs : PendingFeeds.keySet()) {
if (ExhaustedFeeds.contains(fs)) {
Log.i(this.getClass().getName(), "No more stories for feed set: " + fs);
return;
}
if (!FeedPagesSeen.containsKey(fs)) {
FeedPagesSeen.put(fs, 0);
FeedStoriesSeen.put(fs, 0);
}
int pageNumber = FeedPagesSeen.get(fs);
int totalStoriesSeen = FeedStoriesSeen.get(fs);
if (ExhaustedFeeds.contains(fs)) {
Log.i(this.getClass().getName(), "No more stories for feed set: " + fs);
handledFeeds.add(fs);
continue feedloop;
}
StoryOrder order = PrefsUtils.getStoryOrder(this, fs);
ReadFilter filter = PrefsUtils.getReadFilter(this, fs);
while (totalStoriesSeen < PendingFeedTarget) {
if (stopSync()) return;
if (!fs.equals(PendingFeed)) return; // the active view has changed
StorySyncRunning = true;
NbActivity.updateAllActivities(false);
if (!FeedPagesSeen.containsKey(fs)) {
FeedPagesSeen.put(fs, 0);
FeedStoriesSeen.put(fs, 0);
pageNumber++;
StoriesResponse apiResponse = apiManager.getStories(fs, pageNumber, order, filter);
if (! isStoryResponseGood(apiResponse)) return;
FeedPagesSeen.put(fs, pageNumber);
totalStoriesSeen += apiResponse.stories.length;
FeedStoriesSeen.put(fs, totalStoriesSeen);
insertStories(apiResponse);
NbActivity.updateAllActivities(true);
if (apiResponse.stories.length == 0) {
ExhaustedFeeds.add(fs);
return;
}
int pageNumber = FeedPagesSeen.get(fs);
int totalStoriesSeen = FeedStoriesSeen.get(fs);
StoryOrder order = PrefsUtils.getStoryOrder(this, fs);
ReadFilter filter = PrefsUtils.getReadFilter(this, fs);
pageloop: while (totalStoriesSeen < PendingFeeds.get(fs)) {
if (stopSync()) return;
pageNumber++;
StoriesResponse apiResponse = apiManager.getStories(fs, pageNumber, order, filter);
if (! isStoryResponseGood(apiResponse)) break feedloop;
FeedPagesSeen.put(fs, pageNumber);
totalStoriesSeen += apiResponse.stories.length;
FeedStoriesSeen.put(fs, totalStoriesSeen);
insertStories(apiResponse);
NbActivity.updateAllActivities(true);
if (apiResponse.stories.length == 0) {
ExhaustedFeeds.add(fs);
break pageloop;
}
}
handledFeeds.add(fs);
}
PendingFeeds.keySet().removeAll(handledFeeds);
} finally {
synchronized (PENDING_FEED_MUTEX) {
if (fs.equals(PendingFeed)) PendingFeed = null;
}
if (StorySyncRunning) {
StorySyncRunning = false;
NbActivity.updateAllActivities(false);
@ -540,7 +540,7 @@ public class NBSyncService extends Service {
* Is there a sync for a given FeedSet running?
*/
public static boolean isFeedSetSyncing(FeedSet fs) {
return (PendingFeeds.containsKey(fs) && StorySyncRunning);
return (fs.equals(PendingFeed) && StorySyncRunning);
}
public static String getSyncStatusMessage() {
@ -589,31 +589,39 @@ public class NBSyncService extends Service {
return false;
}
synchronized (PendingFeeds) {
synchronized (PENDING_FEED_MUTEX) {
Integer alreadyPending = 0;
if (fs.equals(PendingFeed)) alreadyPending = PendingFeedTarget;
Integer alreadySeen = FeedStoriesSeen.get(fs);
Integer alreadyRequested = PendingFeeds.get(fs);
if (alreadySeen == null) alreadySeen = 0;
if (alreadyRequested == null) alreadyRequested = 0;
if ((callerSeen >= 0) && (alreadySeen > callerSeen)) {
if (callerSeen < alreadySeen) {
// the caller is probably filtering and thinks they have fewer than we do, so
// update our count to agree with them, and force-allow another requet
alreadySeen = callerSeen;
FeedStoriesSeen.put(fs, callerSeen);
alreadyRequested = 0;
alreadyPending = 0;
}
if (AppConstants.VERBOSE_LOG) Log.d(NBSyncService.class.getName(), "have:" + alreadySeen + " want:" + desiredStoryCount + " pending:" + alreadyPending);
if (desiredStoryCount <= alreadySeen) {
return false;
}
if (AppConstants.VERBOSE_LOG) Log.d(NBSyncService.class.getName(), "have:" + alreadySeen + " want:" + desiredStoryCount + " requested:" + alreadyRequested);
if (desiredStoryCount <= alreadyRequested) {
if (desiredStoryCount <= alreadyPending) {
return false;
}
}
PendingFeeds.put(fs, desiredStoryCount);
PendingFeed = fs;
PendingFeedTarget = desiredStoryCount;
}
return true;
}
public static void clearPendingStoryRequest() {
synchronized (PENDING_FEED_MUTEX) {
PendingFeed = null;
}
}
public static void resetFeeds() {
ExhaustedFeeds.clear();
FeedPagesSeen.clear();