bigbluebutton-Github/bigbluebutton-html5/imports/ui/components/connection-status/status-helper/component.jsx
prlanzarin 24ae746a88 fix(connection-status): jitter causes false positive critical alerts
Jitter evaluation, as an alert trigger, was changed in 3.0 to get the internal
average jitter used in the conn-status component data (which is total jitter
delay divided by jitterbuffer emit events). This was done accidentally and that
metric is _very_ different from the one used in 2.7 (point-in-time jitter from
remote-inbound-rtp/inbound-rtp, highest on the interval, gathered on
/utils/stats.js).  The alert thresholds were preserved, which makes it overly
sensitive in regards to jitter (and thus causes it to be critical whenever the
user is in audio).

Remove jitter as a connection status alert trigger, which fixes the
false positive. The implementation on <= 2.7 is also not ideal - if
anything, it generates false negatives. That's why I'm removing jitter for
the time being since it's ill-suited (at least in the way it's used)
for what we want to achieve.
2024-07-30 18:59:49 +00:00

130 lines
3.4 KiB
JavaScript

import React, { Fragment, PureComponent } from 'react';
import { defineMessages, injectIntl } from 'react-intl';
import { useReactiveVar } from '@apollo/client';
import Styled from './styles';
import Icon from '/imports/ui/components/connection-status/icon/component';
import SettingsMenuContainer from '/imports/ui/components/settings/container';
import connectionStatus from '/imports/ui/core/graphql/singletons/connectionStatus';
import { getWorstStatus } from '../service';
const intlMessages = defineMessages({
label: {
id: 'app.connection-status.label',
description: 'Connection status label',
},
settings: {
id: 'app.connection-status.settings',
description: 'Connection settings label',
},
});
class ConnectionStatusIcon extends PureComponent {
constructor(props) {
super(props);
this.state = { isSettingsMenuModalOpen: false };
this.setSettingsMenuModalIsOpen = this.setSettingsMenuModalIsOpen.bind(this);
}
// eslint-disable-next-line
renderIcon(level = 'normal') {
return (
<Styled.IconWrapper>
<Icon
level={level}
grayscale
/>
</Styled.IconWrapper>
);
}
openAdjustSettings() {
this.setSettingsMenuModalIsOpen(true);
}
setSettingsMenuModalIsOpen(value) {
const { closeModal } = this.props;
this.setState({ isSettingsMenuModalOpen: value });
if (!value) {
closeModal();
}
}
render() {
const {
intl,
currentStatus,
} = this.props;
let color;
switch (currentStatus) {
case 'warning':
color = 'success';
break;
case 'danger':
color = 'warning';
break;
case 'critical':
color = 'danger';
break;
default:
color = 'success';
}
const { isSettingsMenuModalOpen } = this.state;
return (
<>
<Styled.StatusIconWrapper color={color}>
{this.renderIcon(currentStatus)}
</Styled.StatusIconWrapper>
<Styled.Label>
{intl.formatMessage(intlMessages.label)}
</Styled.Label>
{(currentStatus === 'critical' || currentStatus === 'danger') || isSettingsMenuModalOpen
? (
<div>
<Styled.Settings
// eslint-disable-next-line
onClick={this.openAdjustSettings.bind(this)}
role="button"
>
{intl.formatMessage(intlMessages.settings)}
</Styled.Settings>
{isSettingsMenuModalOpen
? (
<SettingsMenuContainer
selectedTab={2}
{...{
onRequestClose: () => this.setSettingsMenuModalIsOpen(false),
priority: 'medium',
setIsOpen: this.setSettingsMenuModalIsOpen,
isOpen: isSettingsMenuModalOpen,
}}
/>
) : null}
</div>
)
: (
<div>&nbsp;</div>
)}
</>
);
}
}
const WrapConnectionStatus = (props) => {
const rttStatus = useReactiveVar(connectionStatus.getRttStatusVar());
const packetLossStatus = useReactiveVar(connectionStatus.getPacketLossStatusVar());
const status = getWorstStatus([rttStatus, packetLossStatus]);
return (
<ConnectionStatusIcon
{...props}
currentStatus={status}
/>
);
};
export default injectIntl(WrapConnectionStatus);