From 932c5bf58cff412dce86b9c1f14aeb5fb99d3f18 Mon Sep 17 00:00:00 2001 From: Tainan Felipe Date: Wed, 21 Aug 2019 14:42:37 -0300 Subject: [PATCH] Fix nav bar performance issue and move recordProp to own collection --- .../imports/api/meetings/index.js | 3 +- .../server/handlers/recordingStatusChange.js | 6 ++-- .../server/handlers/recordingTimerChange.js | 6 ++-- .../server/methods/toggleRecording.js | 8 ++--- .../meetings/server/modifiers/addMeeting.js | 33 +++++++++++++++-- .../imports/api/meetings/server/publishers.js | 17 ++++++++- .../ui/components/actions-bar/component.jsx | 10 ------ .../ui/components/actions-bar/container.jsx | 15 -------- .../ui/components/actions-bar/service.js | 1 - .../ui/components/nav-bar/component.jsx | 29 ++++++--------- .../ui/components/nav-bar/container.jsx | 35 ++++++------------- .../nav-bar/recording-indicator/component.jsx | 4 ++- .../imports/ui/components/nav-bar/service.js | 4 +-- .../ui/components/recording/container.jsx | 4 +-- .../ui/components/subscriptions/component.jsx | 2 +- 15 files changed, 89 insertions(+), 88 deletions(-) diff --git a/bigbluebutton-html5/imports/api/meetings/index.js b/bigbluebutton-html5/imports/api/meetings/index.js index 1324a4a61f..363ba6a637 100644 --- a/bigbluebutton-html5/imports/api/meetings/index.js +++ b/bigbluebutton-html5/imports/api/meetings/index.js @@ -1,6 +1,7 @@ import { Meteor } from 'meteor/meteor'; const Meetings = new Mongo.Collection('meetings'); +const RecordMeetings = new Mongo.Collection('record-meetings'); if (Meteor.isServer) { // types of queries for the meetings: @@ -8,5 +9,5 @@ if (Meteor.isServer) { Meetings._ensureIndex({ meetingId: 1 }); } - +export { RecordMeetings }; export default Meetings; diff --git a/bigbluebutton-html5/imports/api/meetings/server/handlers/recordingStatusChange.js b/bigbluebutton-html5/imports/api/meetings/server/handlers/recordingStatusChange.js index bb87adf0bd..eff4978c97 100644 --- a/bigbluebutton-html5/imports/api/meetings/server/handlers/recordingStatusChange.js +++ b/bigbluebutton-html5/imports/api/meetings/server/handlers/recordingStatusChange.js @@ -1,5 +1,5 @@ import { check } from 'meteor/check'; -import Meetings from '/imports/api/meetings'; +import { RecordMeetings } from '/imports/api/meetings'; import Logger from '/imports/startup/server/logger'; export default function handleRecordingStatusChange({ body }, meetingId) { @@ -11,7 +11,7 @@ export default function handleRecordingStatusChange({ body }, meetingId) { }; const modifier = { - $set: { 'recordProp.recording': recording }, + $set: { recording }, }; const cb = (err, numChanged) => { @@ -25,5 +25,5 @@ export default function handleRecordingStatusChange({ body }, meetingId) { } }; - return Meetings.upsert(selector, modifier, cb); + return RecordMeetings.upsert(selector, modifier, cb); } diff --git a/bigbluebutton-html5/imports/api/meetings/server/handlers/recordingTimerChange.js b/bigbluebutton-html5/imports/api/meetings/server/handlers/recordingTimerChange.js index 7f79759927..9e92c566ca 100755 --- a/bigbluebutton-html5/imports/api/meetings/server/handlers/recordingTimerChange.js +++ b/bigbluebutton-html5/imports/api/meetings/server/handlers/recordingTimerChange.js @@ -1,5 +1,5 @@ import { check } from 'meteor/check'; -import Meetings from '/imports/api/meetings'; +import { RecordMeetings } from '/imports/api/meetings'; import Logger from '/imports/startup/server/logger'; export default function handleRecordingStatusChange({ body }, meetingId) { @@ -16,7 +16,7 @@ export default function handleRecordingStatusChange({ body }, meetingId) { }; const modifier = { - $set: { 'recordProp.time': time }, + $set: { time }, }; const cb = (err) => { @@ -25,5 +25,5 @@ export default function handleRecordingStatusChange({ body }, meetingId) { } }; - return Meetings.upsert(selector, modifier, cb); + return RecordMeetings.upsert(selector, modifier, cb); } diff --git a/bigbluebutton-html5/imports/api/meetings/server/methods/toggleRecording.js b/bigbluebutton-html5/imports/api/meetings/server/methods/toggleRecording.js index 775fa30eb9..4d708c0564 100644 --- a/bigbluebutton-html5/imports/api/meetings/server/methods/toggleRecording.js +++ b/bigbluebutton-html5/imports/api/meetings/server/methods/toggleRecording.js @@ -2,7 +2,7 @@ import { check } from 'meteor/check'; import Logger from '/imports/startup/server/logger'; import { Meteor } from 'meteor/meteor'; import RedisPubSub from '/imports/startup/server/redis'; -import Meetings from '/imports/api/meetings'; +import { RecordMeetings } from '/imports/api/meetings'; import Users from '/imports/api/users'; export default function toggleRecording(credentials) { @@ -20,14 +20,14 @@ export default function toggleRecording(credentials) { let meetingRecorded; let allowedToRecord; - const meetingObject = Meetings.findOne({ meetingId }); + const recordObject = RecordMeetings.findOne({ meetingId }); - if (meetingObject != null) { + if (recordObject != null) { const { allowStartStopRecording, recording, record, - } = meetingObject.recordProp; + } = recordObject; meetingRecorded = recording; allowedToRecord = record && allowStartStopRecording; diff --git a/bigbluebutton-html5/imports/api/meetings/server/modifiers/addMeeting.js b/bigbluebutton-html5/imports/api/meetings/server/modifiers/addMeeting.js index aac62a62b0..62d8733a31 100755 --- a/bigbluebutton-html5/imports/api/meetings/server/modifiers/addMeeting.js +++ b/bigbluebutton-html5/imports/api/meetings/server/modifiers/addMeeting.js @@ -3,7 +3,7 @@ import { check, Match, } from 'meteor/check'; -import Meetings from '/imports/api/meetings'; +import Meetings, { RecordMeetings } from '/imports/api/meetings'; import Logger from '/imports/startup/server/logger'; import createNote from '/imports/api/note/server/methods/createNote'; import createCaptions from '/imports/api/captions/server/methods/createCaptions'; @@ -86,7 +86,12 @@ export default function addMeeting(meeting) { }, }); - const newMeeting = meeting; + const { + recordProp, + ...restProps + } = meeting; + + const newMeeting = restProps; const selector = { meetingId, @@ -145,5 +150,29 @@ export default function addMeeting(meeting) { } }; + const cbRecord = (err, numChanged) => { + if (err) { + Logger.error(`Adding record prop to collection: ${err}`); + return; + } + + const { + insertedId, + } = numChanged; + + if (insertedId) { + Logger.info(`Added record prop id=${meetingId}`); + } + + if (numChanged) { + Logger.info(`Upserted record prop id=${meetingId}`); + } + }; + + RecordMeetings.upsert(selector, { + meetingId, + ...recordProp, + }, cbRecord); + return Meetings.upsert(selector, modifier, cb); } diff --git a/bigbluebutton-html5/imports/api/meetings/server/publishers.js b/bigbluebutton-html5/imports/api/meetings/server/publishers.js index de5a102cbe..8207c0368f 100755 --- a/bigbluebutton-html5/imports/api/meetings/server/publishers.js +++ b/bigbluebutton-html5/imports/api/meetings/server/publishers.js @@ -1,6 +1,6 @@ import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; -import Meetings from '/imports/api/meetings'; +import Meetings, { RecordMeetings } from '/imports/api/meetings'; import Users from '/imports/api/users'; import Logger from '/imports/startup/server/logger'; @@ -46,3 +46,18 @@ function publish(...args) { } Meteor.publish('meetings', publish); + +function recordMeetings(credentials) { + const { meetingId, requesterUserId, requesterToken } = credentials; + check(meetingId, String); + check(requesterUserId, String); + check(requesterToken, String); + + return RecordMeetings.find({ meetingId }); +} +function recordPublish(...args) { + const boundMeetings = recordMeetings.bind(this); + return boundMeetings(...args); +} + +Meteor.publish('record-meetings', recordPublish); diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/component.jsx b/bigbluebutton-html5/imports/ui/components/actions-bar/component.jsx index 0dd932bcdc..8eac8315ed 100755 --- a/bigbluebutton-html5/imports/ui/components/actions-bar/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/component.jsx @@ -42,7 +42,6 @@ class ActionsBar extends PureComponent { handleUnshareScreen, isVideoBroadcasting, isUserModerator, - recordSettingsList, toggleRecording, screenSharingCheck, enableVideo, @@ -62,12 +61,6 @@ class ActionsBar extends PureComponent { isThereCurrentPresentation, } = this.props; - const { - allowStartStopRecording, - recording: isRecording, - record, - } = recordSettingsList; - const actionBarClasses = {}; const { enabled: enableExternalVideo } = Meteor.settings.public.externalVideoPlayer; @@ -81,10 +74,7 @@ class ActionsBar extends PureComponent { isUserPresenter, isUserModerator, isPollingEnabled, - allowStartStopRecording, allowExternalVideo: enableExternalVideo, - isRecording, - record, toggleRecording, handleTakePresenter, intl, diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx b/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx index 3cee761cd4..e28c051922 100644 --- a/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx @@ -3,7 +3,6 @@ import { Meteor } from 'meteor/meteor'; import { withTracker } from 'meteor/react-meteor-data'; import { injectIntl } from 'react-intl'; import getFromUserSettings from '/imports/ui/services/users-settings'; -import Meetings from '/imports/api/meetings'; import Auth from '/imports/ui/services/auth'; import PresentationService from '/imports/ui/components/presentation/service'; import Presentations from '/imports/api/presentations'; @@ -30,18 +29,6 @@ const ActionsBarContainer = props => ; export default withTracker(() => { const POLLING_ENABLED = Meteor.settings.public.poll.enabled; - Meetings.find({ meetingId: Auth.meetingID }, { fields: { recordProp: 1 } }).observeChanges({ - changed: (id, fields) => { - if (fields.recordProp && fields.recordProp.recording) { - this.window.parent.postMessage({ response: 'recordingStarted' }, '*'); - } - - if (fields.recordProp && !fields.recordProp.recording) { - this.window.parent.postMessage({ response: 'recordingStopped' }, '*'); - } - }, - }); - const getCurrentPresentation = meetingId => Presentations.findOne({ meetingId, current: true, @@ -56,8 +43,6 @@ export default withTracker(() => { handleShareScreen: onFail => shareScreen(onFail), handleUnshareScreen: () => unshareScreen(), isVideoBroadcasting: isVideoBroadcasting(), - recordSettingsList: Service.recordSettingsList(), - toggleRecording: Service.toggleRecording, screenSharingCheck: getFromUserSettings('enableScreensharing', Meteor.settings.public.kurento.enableScreensharing), enableVideo: getFromUserSettings('enableVideo', Meteor.settings.public.kurento.enableVideo), isLayoutSwapped: getSwapLayout() && shouldEnableSwapLayout(), diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/service.js b/bigbluebutton-html5/imports/ui/components/actions-bar/service.js index 2b0fcc132f..97c9f9ca71 100755 --- a/bigbluebutton-html5/imports/ui/components/actions-bar/service.js +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/service.js @@ -26,7 +26,6 @@ const takePresenterRole = () => makeCall('assignPresenter', Auth.userID); export default { isUserPresenter: () => Users.findOne({ userId: Auth.userID }).presenter, isUserModerator: () => Users.findOne({ userId: Auth.userID }).role === ROLE_MODERATOR, - recordSettingsList: () => Meetings.findOne({ meetingId: Auth.meetingID }).recordProp, meetingIsBreakout: () => Meetings.findOne({ meetingId: Auth.meetingID }).meetingProp.isBreakout, meetingName: () => Meetings.findOne({ meetingId: Auth.meetingID }).meetingProp.name, users: () => Users.find({ connectionStatus: 'online', meetingId: Auth.meetingID, clientType: { $ne: DIAL_IN_USER } }).fetch(), diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx b/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx index 051ef3d842..ab6d9a1c2d 100755 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx @@ -30,22 +30,12 @@ const intlMessages = defineMessages({ const propTypes = { presentationTitle: PropTypes.string, hasUnreadMessages: PropTypes.bool, - recordProps: PropTypes.shape({ - time: PropTypes.number, - recording: PropTypes.bool, - }), shortcuts: PropTypes.string, }; const defaultProps = { presentationTitle: 'Default Room Title', hasUnreadMessages: false, - recordProps: { - allowStartStopRecording: false, - autoStartRecording: false, - record: false, - recording: false, - }, shortcuts: '', }; @@ -73,11 +63,6 @@ class NavBar extends React.PureComponent { } } - componentDidUpdate(prevProps) { - console.error('prev', { ...prevProps }); - console.error('props', { ...this.props }); - } - componentWillUnmount() { clearInterval(this.interval); } @@ -85,7 +70,6 @@ class NavBar extends React.PureComponent { render() { const { hasUnreadMessages, - recordProps, isExpanded, intl, shortcuts: TOGGLE_USERLIST_AK, @@ -93,6 +77,11 @@ class NavBar extends React.PureComponent { isBreakoutRoom, presentationTitle, amIModerator, + allowStartStopRecording, + autoStartRecording, + record, + recording, + time, } = this.props; @@ -122,11 +111,15 @@ class NavBar extends React.PureComponent {

{presentationTitle}

- {recordProps.record + {record ? | : null} diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/container.jsx b/bigbluebutton-html5/imports/ui/components/nav-bar/container.jsx index 187c7ae457..a1789c7c76 100755 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/container.jsx @@ -2,7 +2,7 @@ import React from 'react'; import { Meteor } from 'meteor/meteor'; import { withTracker } from 'meteor/react-meteor-data'; import { Session } from 'meteor/session'; -import Meetings from '/imports/api/meetings'; +import Meetings, { RecordMeetings } from '/imports/api/meetings'; import Users from '/imports/api/users'; import Auth from '/imports/ui/services/auth'; import { meetingIsBreakout } from '/imports/ui/components/app/service'; @@ -20,14 +20,6 @@ const NavBarContainer = ({ children, ...props }) => ( ); - -const recordProps = { - allowStartStopRecording: false, - autoStartRecording: false, - record: false, - recording: false, -}; - export default withTracker(() => { const CLIENT_TITLE = getFromUserSettings('clientTitle', PUBLIC_CONFIG.app.clientTitle); @@ -36,6 +28,7 @@ export default withTracker(() => { const meetingObject = Meetings.findOne({ meetingId, }); + const recordObeject = RecordMeetings.findOne({ meetingId }); if (meetingObject != null) { meetingTitle = meetingObject.meetingProp.name; @@ -50,13 +43,13 @@ export default withTracker(() => { return hasUnreadMessages; }; - Meetings.find({ meetingId: Auth.meetingID }, { fields: { recordProp: 1 } }).observeChanges({ + RecordMeetings.find({ meetingId: Auth.meetingID }, { fields: { recording: 1 } }).observeChanges({ changed: (id, fields) => { - if (fields.recordProp && fields.recordProp.recording) { + if (fields && fields.recording) { this.window.parent.postMessage({ response: 'recordingStarted' }, '*'); } - if (fields.recordProp && !fields.recordProp.recording) { + if (fields && !fields.recording) { this.window.parent.postMessage({ response: 'recordingStopped' }, '*'); } }, @@ -74,17 +67,7 @@ export default withTracker(() => { const toggleUserList = () => { Session.set('isUserListOpen', !isExpanded); }; - const { recordProp } = meetingObject; - // const recordProps = { - // allowStartStopRecording: recordProp && recordProp.allowStartStopRecording, - // autoStartRecording: recordProp && recordProp.autoStartRecording, - // record: recordProp && recordProp.record, - // recording: recordProp && recordProp.recording, - // }; - recordProps.allowStartStopRecording = recordProp && recordProp.allowStartStopRecording; - recordProps.autoStartRecording = recordProp && recordProp.autoStartRecording; - recordProps.record = recordProp && recordProp.record; - recordProps.recording = recordProp && recordProp.recording; + return { amIModerator, isExpanded, @@ -95,7 +78,11 @@ export default withTracker(() => { presentationTitle: meetingTitle, hasUnreadMessages, isBreakoutRoom, - recordProps, toggleUserList, + allowStartStopRecording: !!(recordObeject && recordObeject.allowStartStopRecording), + autoStartRecording: recordObeject && recordObeject.autoStartRecording, + record: recordObeject && recordObeject.record, + recording: recordObeject && recordObeject.recording, + time: recordObeject && recordObeject.time, }; })(NavBarContainer); diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/recording-indicator/component.jsx b/bigbluebutton-html5/imports/ui/components/nav-bar/recording-indicator/component.jsx index fe7dbf24d9..ca2bd2266d 100755 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/recording-indicator/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/recording-indicator/component.jsx @@ -69,7 +69,8 @@ class RecordingIndicator extends PureComponent { } componentDidUpdate() { - if (!this.props.recording) { + const { recording } = this.props; + if (!recording) { clearInterval(this.interval); this.interval = null; } else if (this.interval === null) { @@ -97,6 +98,7 @@ class RecordingIndicator extends PureComponent { intl, allowStartStopRecording, } = this.props; + const { time } = this.state; if (!record) return null; diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/service.js b/bigbluebutton-html5/imports/ui/components/nav-bar/service.js index 7f02882151..a6db9abfdf 100755 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/service.js +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/service.js @@ -1,6 +1,6 @@ import Auth from '/imports/ui/services/auth'; import { makeCall } from '/imports/ui/services/api'; -import Meetings from '/imports/api/meetings'; +import RecordMeetings from '/imports/api/meetings'; const processOutsideToggleRecording = (e) => { switch (e.data) { @@ -9,7 +9,7 @@ const processOutsideToggleRecording = (e) => { break; } case 'c_recording_status': { - const recordingState = Meetings.findOne({ meetingId: Auth.meetingID }).recordProp.recording; + const recordingState = (RecordMeetings.findOne({ meetingId: Auth.meetingID }) || {}).recording; const recordingMessage = recordingState ? 'recordingStarted' : 'recordingStopped'; this.window.parent.postMessage({ response: recordingMessage }, '*'); break; diff --git a/bigbluebutton-html5/imports/ui/components/recording/container.jsx b/bigbluebutton-html5/imports/ui/components/recording/container.jsx index 9165c8a5ef..9520003b63 100755 --- a/bigbluebutton-html5/imports/ui/components/recording/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/recording/container.jsx @@ -2,14 +2,14 @@ import React from 'react'; import { withTracker } from 'meteor/react-meteor-data'; import { withModalMounter } from '/imports/ui/components/modal/service'; import { makeCall } from '/imports/ui/services/api'; -import Meetings from '/imports/api/meetings'; +import { RecordMeetings } from '/imports/api/meetings'; import Auth from '/imports/ui/services/auth'; import RecordingComponent from './component'; const RecordingContainer = props => ; export default withModalMounter(withTracker(({ mountModal }) => { - const { recording, time } = Meetings.findOne({ meetingId: Auth.meetingID }).recordProp; + const { recording, time } = RecordMeetings.findOne({ meetingId: Auth.meetingID }); return ({ closeModal: () => mountModal(null), diff --git a/bigbluebutton-html5/imports/ui/components/subscriptions/component.jsx b/bigbluebutton-html5/imports/ui/components/subscriptions/component.jsx index 55ccf33c9b..fa0d5e2f56 100755 --- a/bigbluebutton-html5/imports/ui/components/subscriptions/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/subscriptions/component.jsx @@ -17,7 +17,7 @@ const SUBSCRIPTIONS = [ 'users', 'meetings', 'polls', 'presentations', 'slides', 'slide-positions', 'captions', 'voiceUsers', 'whiteboard-multi-user', 'screenshare', 'group-chat', 'presentation-pods', 'users-settings', 'guestUser', 'users-infos', 'note', - 'network-information', 'ping-pong', 'local-settings', 'users-typing', + 'network-information', 'ping-pong', 'local-settings', 'users-typing', 'record-meetings', ]; class Subscriptions extends Component {