Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add code to NewDot to handle both new and old Pusher event types #18192

Merged
merged 14 commits into from
May 12, 2023
7 changes: 4 additions & 3 deletions src/libs/Pusher/EventType.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
*/
export default {
REPORT_COMMENT: 'reportComment',
PREFERRED_LOCALE: 'preferredLocale',
EXPENSIFY_CARD_UPDATE: 'expensifyCardUpdate',
SCREEN_SHARE_REQUEST: 'screenshareRequest',
Comment on lines -7 to -9
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the migration plan? We start sending both old and new events from the backend, then remove the old one when this is released?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it's more simple than that. Web-E just needed to be updated to send these three events as Onyx updates, which NewDot already supports. Once that Web-E change is in production, then the HOLD can be removed on this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am confused... if web-e stopped sending the old events, then all existing apps will be broken till this is deployed, no??

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. Older versions of NewDot (for like the past several months) can all handle the onyx update event. Web-E is just switching over to using that.

ONYX_API_UPDATE: 'onyxApiUpdate',
USER_IS_TYPING: 'client-userIsTyping',
MULTIPLE_EVENTS: 'multipleEvents',
MULTIPLE_EVENT_TYPE: {
ONYX_API_UPDATE: 'onyxApiUpdate',
},
};
24 changes: 24 additions & 0 deletions src/libs/PusherUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,28 @@ import NetworkConnection from './NetworkConnection';
import * as Pusher from './Pusher/pusher';
import CONST from '../CONST';

// Keeps track of all the callbacks that need triggered for each event type
const multiEventCallbackMapping = {};

/**
* @param {String} eventType
* @param {Function} callback
*/
function subscribeToMultiEvent(eventType, callback) {
multiEventCallbackMapping[eventType] = callback;
}

/**
* @param {String} eventType
* @param {Mixed} data
*/
function triggerMultiEventHandler(eventType, data) {
if (!multiEventCallbackMapping[eventType]) {
return;
}
multiEventCallbackMapping[eventType](data);
}

/**
* Abstraction around subscribing to private user channel events. Handles all logs and errors automatically.
*
Expand Down Expand Up @@ -44,4 +66,6 @@ function subscribeToPrivateUserChannelEvent(eventName, accountID, onEvent) {

export default {
subscribeToPrivateUserChannelEvent,
subscribeToMultiEvent,
triggerMultiEventHandler,
};
91 changes: 30 additions & 61 deletions src/libs/actions/User.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,10 @@ import Onyx from 'react-native-onyx';
import moment from 'moment';
import ONYXKEYS from '../../ONYXKEYS';
import * as API from '../API';
import CONFIG from '../../CONFIG';
import CONST from '../../CONST';
import Navigation from '../Navigation/Navigation';
import ROUTES from '../../ROUTES';
import * as Pusher from '../Pusher/pusher';
import Log from '../Log';
import NetworkConnection from '../NetworkConnection';
import Growl from '../Growl';
import * as Localize from '../Localize';
import * as Link from './Link';
Expand Down Expand Up @@ -551,81 +548,54 @@ function triggerNotifications(onyxUpdates) {
}

/**
* Initialize our pusher subscription to listen for user changes
* Handles the newest events from Pusher where a single mega multipleEvents contains
* an array of singular events all in one event
*/
function subscribeToUserEvents() {
// If we don't have the user's accountID yet we can't subscribe so return early
if (!currentUserAccountID) {
return;
}
function subscribeToUserEventsUsingMultipleEventType() {
// Handles the mega multipleEvents from Pusher which contains an array of single events.
// Each single event is passed to PusherUtils in order to trigger the callbacks for that event
PusherUtils.subscribeToPrivateUserChannelEvent(Pusher.TYPE.MULTIPLE_EVENTS, currentUserAccountID, (pushJSON) => {
_.each(pushJSON, (multipleEvent) => {
PusherUtils.triggerMultiEventHandler(multipleEvent.eventType, multipleEvent.data);
});
});

const pusherChannelName = `${CONST.PUSHER.PRIVATE_USER_CHANNEL_PREFIX}${currentUserAccountID}${CONFIG.PUSHER.SUFFIX}`;
// Handles Onyx updates coming from Pusher through the mega multipleEvents.
PusherUtils.subscribeToMultiEvent(Pusher.TYPE.MULTIPLE_EVENT_TYPE.ONYX_API_UPDATE, (pushJSON) => {
SequentialQueue.getCurrentRequest().then(() => {
Onyx.update(pushJSON);
triggerNotifications(pushJSON);
});
});
}

/**
* Handles the older Pusher events where each event was pushed separately. This is considered legacy code
* and should not be updated. Once the server is sending all pusher events using the multipleEvents type,
* then this code can be removed. This will be handled in https://github.com/Expensify/Expensify/issues/279347
* @deprecated
*/
function subscribeToUserDeprecatedEvents() {
// Receive any relevant Onyx updates from the server
PusherUtils.subscribeToPrivateUserChannelEvent(Pusher.TYPE.ONYX_API_UPDATE, currentUserAccountID, (pushJSON) => {
SequentialQueue.getCurrentRequest().then(() => {
Onyx.update(pushJSON);
triggerNotifications(pushJSON);
});
});

// Live-update an user's preferred locale
Pusher.subscribe(
pusherChannelName,
Pusher.TYPE.PREFERRED_LOCALE,
(pushJSON) => {
Onyx.merge(ONYXKEYS.NVP_PREFERRED_LOCALE, pushJSON.preferredLocale);
},
() => {
NetworkConnection.triggerReconnectionCallbacks('pusher re-subscribed to private user channel');
},
).catch((error) => {
Log.hmmm('[User] Failed to subscribe to Pusher channel', false, {error, pusherChannelName, eventName: Pusher.TYPE.PREFERRED_LOCALE});
});

// Subscribe to screen share requests sent by GuidesPlus agents
Pusher.subscribe(
pusherChannelName,
Pusher.TYPE.SCREEN_SHARE_REQUEST,
(pushJSON) => {
Onyx.merge(ONYXKEYS.SCREEN_SHARE_REQUEST, pushJSON);
},
() => {
NetworkConnection.triggerReconnectionCallbacks('pusher re-subscribed to private user channel');
},
).catch((error) => {
Log.hmmm('[User] Failed to subscribe to Pusher channel', false, {error, pusherChannelName, eventName: Pusher.TYPE.SCREEN_SHARE_REQUEST});
});
}

/**
* Subscribes to Expensify Card updates when checking loginList for private domains
* Initialize our pusher subscription to listen for user changes
*/
function subscribeToExpensifyCardUpdates() {
function subscribeToUserEvents() {
// If we don't have the user's accountID yet we can't subscribe so return early
if (!currentUserAccountID) {
return;
}

const pusherChannelName = `${CONST.PUSHER.PRIVATE_USER_CHANNEL_PREFIX}${currentUserAccountID}${CONFIG.PUSHER.SUFFIX}`;

// Handle Expensify Card approval flow updates
Pusher.subscribe(
pusherChannelName,
Pusher.TYPE.EXPENSIFY_CARD_UPDATE,
(pushJSON) => {
if (pushJSON.isUsingExpensifyCard) {
Onyx.merge(ONYXKEYS.USER, {isUsingExpensifyCard: pushJSON.isUsingExpensifyCard, isCheckingDomain: null});
Pusher.unsubscribe(pusherChannelName, Pusher.TYPE.EXPENSIFY_CARD_UPDATE);
} else {
Onyx.merge(ONYXKEYS.USER, {isCheckingDomain: pushJSON.isCheckingDomain});
}
},
() => {
NetworkConnection.triggerReconnectionCallbacks('pusher re-subscribed to private user channel');
},
).catch((error) => {
Log.info('[User] Failed to subscribe to Pusher channel', false, {error, pusherChannelName, eventName: Pusher.TYPE.EXPENSIFY_CARD_UPDATE});
});
subscribeToUserEventsUsingMultipleEventType();
subscribeToUserDeprecatedEvents();
}

/**
Expand Down Expand Up @@ -776,7 +746,6 @@ export {
updatePreferredSkinTone,
setShouldUseStagingServer,
clearUserErrorMessage,
subscribeToExpensifyCardUpdates,
updateFrequentlyUsedEmojis,
joinScreenShare,
clearScreenShareRequest,
Expand Down
2 changes: 0 additions & 2 deletions src/pages/ReimbursementAccount/EnableStep.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import userPropTypes from '../settings/userPropTypes';
import Section from '../../components/Section';
import * as Illustrations from '../../components/Icon/Illustrations';
import * as Link from '../../libs/actions/Link';
import * as User from '../../libs/actions/User';
import ScreenWrapper from '../../components/ScreenWrapper';
import * as BankAccounts from '../../libs/actions/ReimbursementAccount';
import WorkspaceResetBankAccountModal from '../workspace/WorkspaceResetBankAccountModal';
Expand Down Expand Up @@ -99,7 +98,6 @@ const EnableStep = (props) => {
text={props.translate('workspace.bankAccount.addWorkEmail')}
onPress={() => {
Link.openOldDotLink(CONST.ADD_SECONDARY_LOGIN_URL);
User.subscribeToExpensifyCardUpdates();
}}
icon={Expensicons.Mail}
style={[styles.mt4]}
Expand Down
2 changes: 0 additions & 2 deletions src/pages/workspace/card/WorkspaceCardVBANoECardView.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import * as Illustrations from '../../../components/Icon/Illustrations';
import UnorderedList from '../../../components/UnorderedList';
import Section from '../../../components/Section';
import * as Link from '../../../libs/actions/Link';
import * as User from '../../../libs/actions/User';
import ONYXKEYS from '../../../ONYXKEYS';
import compose from '../../../libs/compose';
import CONST from '../../../CONST';
Expand Down Expand Up @@ -47,7 +46,6 @@ const WorkspaceCardVBANoECardView = (props) => (
text={props.translate('workspace.card.addWorkEmail')}
onPress={() => {
Link.openOldDotLink(CONST.ADD_SECONDARY_LOGIN_URL);
User.subscribeToExpensifyCardUpdates();
}}
icon={Expensicons.Mail}
style={[styles.mt4]}
Expand Down