Use randomized setTimeout when fallback-polling and re-add since_id (#7522)
This commit is contained in:
		
							parent
							
								
									1e02dc8715
								
							
						
					
					
						commit
						dafd7afc5e
					
				
					 4 changed files with 43 additions and 19 deletions
				
			
		| 
						 | 
				
			
			@ -76,9 +76,14 @@ export function updateNotifications(notification, intlMessages, intlLocale) {
 | 
			
		|||
 | 
			
		||||
const excludeTypesFromSettings = state => state.getIn(['settings', 'notifications', 'shows']).filter(enabled => !enabled).keySeq().toJS();
 | 
			
		||||
 | 
			
		||||
export function expandNotifications({ maxId } = {}) {
 | 
			
		||||
const noOp = () => {};
 | 
			
		||||
 | 
			
		||||
export function expandNotifications({ maxId } = {}, done = noOp) {
 | 
			
		||||
  return (dispatch, getState) => {
 | 
			
		||||
    if (getState().getIn(['notifications', 'isLoading'])) {
 | 
			
		||||
    const notifications = getState().get('notifications');
 | 
			
		||||
 | 
			
		||||
    if (notifications.get('isLoading')) {
 | 
			
		||||
      done();
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -87,6 +92,10 @@ export function expandNotifications({ maxId } = {}) {
 | 
			
		|||
      exclude_types: excludeTypesFromSettings(getState()),
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    if (!maxId && notifications.get('items').size > 0) {
 | 
			
		||||
      params.since_id = notifications.getIn(['items', 0]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    dispatch(expandNotificationsRequest());
 | 
			
		||||
 | 
			
		||||
    api(getState).get('/api/v1/notifications', { params }).then(response => {
 | 
			
		||||
| 
						 | 
				
			
			@ -97,8 +106,10 @@ export function expandNotifications({ maxId } = {}) {
 | 
			
		|||
 | 
			
		||||
      dispatch(expandNotificationsSuccess(response.data, next ? next.uri : null));
 | 
			
		||||
      fetchRelatedRelationships(dispatch, response.data);
 | 
			
		||||
      done();
 | 
			
		||||
    }).catch(error => {
 | 
			
		||||
      dispatch(expandNotificationsFail(error));
 | 
			
		||||
      done();
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,10 +36,9 @@ export function connectTimelineStream (timelineId, path, pollingRefresh = null)
 | 
			
		|||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function refreshHomeTimelineAndNotification (dispatch) {
 | 
			
		||||
  dispatch(expandHomeTimeline());
 | 
			
		||||
  dispatch(expandNotifications());
 | 
			
		||||
}
 | 
			
		||||
const refreshHomeTimelineAndNotification = (dispatch, done) => {
 | 
			
		||||
  dispatch(expandHomeTimeline({}, () => dispatch(expandNotifications({}, done))));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const connectUserStream = () => connectTimelineStream('home', 'user', refreshHomeTimelineAndNotification);
 | 
			
		||||
export const connectCommunityStream = () => connectTimelineStream('community', 'public:local');
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
import { importFetchedStatus, importFetchedStatuses } from './importer';
 | 
			
		||||
import api, { getLinks } from '../api';
 | 
			
		||||
import { Map as ImmutableMap } from 'immutable';
 | 
			
		||||
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
 | 
			
		||||
 | 
			
		||||
export const TIMELINE_UPDATE  = 'TIMELINE_UPDATE';
 | 
			
		||||
export const TIMELINE_DELETE  = 'TIMELINE_DELETE';
 | 
			
		||||
| 
						 | 
				
			
			@ -64,35 +64,44 @@ export function deleteFromTimelines(id) {
 | 
			
		|||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function expandTimeline(timelineId, path, params = {}) {
 | 
			
		||||
const noOp = () => {};
 | 
			
		||||
 | 
			
		||||
export function expandTimeline(timelineId, path, params = {}, done = noOp) {
 | 
			
		||||
  return (dispatch, getState) => {
 | 
			
		||||
    const timeline = getState().getIn(['timelines', timelineId], ImmutableMap());
 | 
			
		||||
 | 
			
		||||
    if (timeline.get('isLoading')) {
 | 
			
		||||
      done();
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!params.max_id && timeline.get('items', ImmutableList()).size > 0) {
 | 
			
		||||
      params.since_id = timeline.getIn(['items', 0]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    dispatch(expandTimelineRequest(timelineId));
 | 
			
		||||
 | 
			
		||||
    api(getState).get(path, { params }).then(response => {
 | 
			
		||||
      const next = getLinks(response).refs.find(link => link.rel === 'next');
 | 
			
		||||
      dispatch(importFetchedStatuses(response.data));
 | 
			
		||||
      dispatch(expandTimelineSuccess(timelineId, response.data, next ? next.uri : null, response.code === 206));
 | 
			
		||||
      done();
 | 
			
		||||
    }).catch(error => {
 | 
			
		||||
      dispatch(expandTimelineFail(timelineId, error));
 | 
			
		||||
      done();
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const expandHomeTimeline         = ({ maxId } = {}) => expandTimeline('home', '/api/v1/timelines/home', { max_id: maxId });
 | 
			
		||||
export const expandPublicTimeline       = ({ maxId } = {}) => expandTimeline('public', '/api/v1/timelines/public', { max_id: maxId });
 | 
			
		||||
export const expandCommunityTimeline    = ({ maxId } = {}) => expandTimeline('community', '/api/v1/timelines/public', { local: true, max_id: maxId });
 | 
			
		||||
export const expandDirectTimeline       = ({ maxId } = {}) => expandTimeline('direct', '/api/v1/timelines/direct', { max_id: maxId });
 | 
			
		||||
export const expandHomeTimeline         = ({ maxId } = {}, done = noOp) => expandTimeline('home', '/api/v1/timelines/home', { max_id: maxId }, done);
 | 
			
		||||
export const expandPublicTimeline       = ({ maxId } = {}, done = noOp) => expandTimeline('public', '/api/v1/timelines/public', { max_id: maxId }, done);
 | 
			
		||||
export const expandCommunityTimeline    = ({ maxId } = {}, done = noOp) => expandTimeline('community', '/api/v1/timelines/public', { local: true, max_id: maxId }, done);
 | 
			
		||||
export const expandDirectTimeline       = ({ maxId } = {}, done = noOp) => expandTimeline('direct', '/api/v1/timelines/direct', { max_id: maxId }, done);
 | 
			
		||||
export const expandAccountTimeline      = (accountId, { maxId, withReplies } = {}) => expandTimeline(`account:${accountId}${withReplies ? ':with_replies' : ''}`, `/api/v1/accounts/${accountId}/statuses`, { exclude_replies: !withReplies, max_id: maxId });
 | 
			
		||||
export const expandAccountFeaturedTimeline = accountId => expandTimeline(`account:${accountId}:pinned`, `/api/v1/accounts/${accountId}/statuses`, { pinned: true });
 | 
			
		||||
export const expandAccountMediaTimeline = (accountId, { maxId } = {}) => expandTimeline(`account:${accountId}:media`, `/api/v1/accounts/${accountId}/statuses`, { max_id: maxId, only_media: true });
 | 
			
		||||
export const expandHashtagTimeline      = (hashtag, { maxId } = {}) => expandTimeline(`hashtag:${hashtag}`, `/api/v1/timelines/tag/${hashtag}`, { max_id: maxId });
 | 
			
		||||
export const expandListTimeline         = (id, { maxId } = {}) => expandTimeline(`list:${id}`, `/api/v1/timelines/list/${id}`, { max_id: maxId });
 | 
			
		||||
export const expandHashtagTimeline      = (hashtag, { maxId } = {}, done = noOp) => expandTimeline(`hashtag:${hashtag}`, `/api/v1/timelines/tag/${hashtag}`, { max_id: maxId }, done);
 | 
			
		||||
export const expandListTimeline         = (id, { maxId } = {}, done = noOp) => expandTimeline(`list:${id}`, `/api/v1/timelines/list/${id}`, { max_id: maxId }, done);
 | 
			
		||||
 | 
			
		||||
export function expandTimelineRequest(timeline) {
 | 
			
		||||
  return {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,21 +1,24 @@
 | 
			
		|||
import WebSocketClient from 'websocket.js';
 | 
			
		||||
 | 
			
		||||
const randomIntUpTo = max => Math.floor(Math.random() * Math.floor(max));
 | 
			
		||||
 | 
			
		||||
export function connectStream(path, pollingRefresh = null, callbacks = () => ({ onDisconnect() {}, onReceive() {} })) {
 | 
			
		||||
  return (dispatch, getState) => {
 | 
			
		||||
    const streamingAPIBaseURL = getState().getIn(['meta', 'streaming_api_base_url']);
 | 
			
		||||
    const accessToken = getState().getIn(['meta', 'access_token']);
 | 
			
		||||
    const { onDisconnect, onReceive } = callbacks(dispatch, getState);
 | 
			
		||||
 | 
			
		||||
    let polling = null;
 | 
			
		||||
 | 
			
		||||
    const setupPolling = () => {
 | 
			
		||||
      polling = setInterval(() => {
 | 
			
		||||
        pollingRefresh(dispatch);
 | 
			
		||||
      }, 20000);
 | 
			
		||||
      pollingRefresh(dispatch, () => {
 | 
			
		||||
        polling = setTimeout(() => setupPolling(), 20000 + randomIntUpTo(20000));
 | 
			
		||||
      });
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const clearPolling = () => {
 | 
			
		||||
      if (polling) {
 | 
			
		||||
        clearInterval(polling);
 | 
			
		||||
        clearTimeout(polling);
 | 
			
		||||
        polling = null;
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
| 
						 | 
				
			
			@ -29,8 +32,9 @@ export function connectStream(path, pollingRefresh = null, callbacks = () => ({
 | 
			
		|||
 | 
			
		||||
      disconnected () {
 | 
			
		||||
        if (pollingRefresh) {
 | 
			
		||||
          setupPolling();
 | 
			
		||||
          polling = setTimeout(() => setupPolling(), randomIntUpTo(40000));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        onDisconnect();
 | 
			
		||||
      },
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -51,6 +55,7 @@ export function connectStream(path, pollingRefresh = null, callbacks = () => ({
 | 
			
		|||
      if (subscription) {
 | 
			
		||||
        subscription.close();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      clearPolling();
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue