ref: remove features/base/conference -> /app cycle

Move call to reloadNow() on CONNECTION_FAILED to
the ./features/app/middleware to avoid importing higher order feature
from the lower level one.
This commit is contained in:
paweldomas 2020-01-02 15:55:46 -06:00 committed by Saúl Ibarra Corretgé
parent e8e70d9d27
commit 6c3968a434
2 changed files with 73 additions and 56 deletions

View File

@ -1,18 +1,27 @@
// @flow
import {
createConnectionEvent,
sendAnalytics
} from '../analytics';
import { SET_ROOM } from '../base/conference';
import {
CONNECTION_ESTABLISHED,
CONNECTION_FAILED,
getURLWithoutParams
} from '../base/connection';
import { MiddlewareRegistry } from '../base/redux';
import { reloadNow } from './actions';
import { _getRouteToRender } from './getRouteToRender';
MiddlewareRegistry.register(store => next => action => {
switch (action.type) {
case CONNECTION_ESTABLISHED:
return _connectionEstablished(store, next, action);
case CONNECTION_FAILED:
return _connectionFailed(store, next, action);
case SET_ROOM:
return _setRoom(store, next, action);
@ -62,6 +71,70 @@ function _connectionEstablished(store, next, action) {
return result;
}
/**
* CONNECTION_FAILED action side effects.
*
* @param {Object} store - The Redux store.
* @param {Dispatch} next - The redux {@code dispatch} function to dispatch the specified {@code action} to
* the specified {@code store}.
* @param {Action} action - The redux action {@code CONNECTION_FAILED} which is being dispatched in the specified
* {@code store}.
* @returns {Object}
* @private
*/
function _connectionFailed({ dispatch, getState }, next, action) {
// In the case of a split-brain error, reload early and prevent further
// handling of the action.
if (_isMaybeSplitBrainError(getState, action)) {
dispatch(reloadNow());
return;
}
return next(action);
}
/**
* Returns whether or not a CONNECTION_FAILED action is for a possible split brain error. A split brain error occurs
* when at least two users join a conference on different bridges. It is assumed the split brain scenario occurs very
* early on in the call.
*
* @param {Function} getState - The redux function for fetching the current state.
* @param {Action} action - The redux action {@code CONNECTION_FAILED} which is being dispatched in the specified
* {@code store}.
* @private
* @returns {boolean}
*/
function _isMaybeSplitBrainError(getState, action) {
const { error } = action;
const isShardChangedError = error
&& error.message === 'item-not-found'
&& error.details
&& error.details.shard_changed;
if (isShardChangedError) {
const state = getState();
const { timeEstablished } = state['features/base/connection'];
const { _immediateReloadThreshold } = state['features/base/config'];
const timeSinceConnectionEstablished = timeEstablished && Date.now() - timeEstablished;
const reloadThreshold = typeof _immediateReloadThreshold === 'number' ? _immediateReloadThreshold : 1500;
const isWithinSplitBrainThreshold = !timeEstablished || timeSinceConnectionEstablished <= reloadThreshold;
sendAnalytics(createConnectionEvent('failed', {
...error,
connectionEstablished: timeEstablished,
splitBrain: isWithinSplitBrainThreshold,
timeSinceConnectionEstablished
}));
return isWithinSplitBrainThreshold;
}
return false;
}
/**
* Navigates to a route in accord with a specific redux state.
*

View File

@ -1,12 +1,10 @@
// @flow
import { reloadNow } from '../../app';
import { openDisplayNamePrompt } from '../../display-name';
import {
ACTION_PINNED,
ACTION_UNPINNED,
createConnectionEvent,
createOfferAnswerFailedEvent,
createPinnedEvent,
sendAnalytics
@ -256,14 +254,6 @@ function _connectionEstablished({ dispatch }, next, action) {
* @returns {Object} The value returned by {@code next(action)}.
*/
function _connectionFailed({ dispatch, getState }, next, action) {
// In the case of a split-brain error, reload early and prevent further
// handling of the action.
if (_isMaybeSplitBrainError(getState, action)) {
dispatch(reloadNow());
return;
}
const result = next(action);
if (typeof beforeUnloadHandler !== 'undefined') {
@ -355,52 +345,6 @@ function _conferenceWillLeave() {
}
}
/**
* Returns whether or not a CONNECTION_FAILED action is for a possible split
* brain error. A split brain error occurs when at least two users join a
* conference on different bridges. It is assumed the split brain scenario
* occurs very early on in the call.
*
* @param {Function} getState - The redux function for fetching the current
* state.
* @param {Action} action - The redux action {@code CONNECTION_FAILED} which is
* being dispatched in the specified {@code store}.
* @private
* @returns {boolean}
*/
function _isMaybeSplitBrainError(getState, action) {
const { error } = action;
const isShardChangedError = error
&& error.message === 'item-not-found'
&& error.details
&& error.details.shard_changed;
if (isShardChangedError) {
const state = getState();
const { timeEstablished } = state['features/base/connection'];
const { _immediateReloadThreshold } = state['features/base/config'];
const timeSinceConnectionEstablished
= timeEstablished && Date.now() - timeEstablished;
const reloadThreshold = typeof _immediateReloadThreshold === 'number'
? _immediateReloadThreshold : 1500;
const isWithinSplitBrainThreshold = !timeEstablished
|| timeSinceConnectionEstablished <= reloadThreshold;
sendAnalytics(createConnectionEvent('failed', {
...error,
connectionEstablished: timeEstablished,
splitBrain: isWithinSplitBrainThreshold,
timeSinceConnectionEstablished
}));
return isWithinSplitBrainThreshold;
}
return false;
}
/**
* Notifies the feature base/conference that the action {@code PIN_PARTICIPANT}
* is being dispatched within a specific redux store. Pins the specified remote