Skip to content

Commit

Permalink
Update publish-alpha
Browse files Browse the repository at this point in the history
  • Loading branch information
raviteja83 authored Sep 18, 2024
2 parents af10282 + fabc234 commit 4e6a405
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 30 deletions.
46 changes: 44 additions & 2 deletions packages/hms-video-store/src/sdk/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { HMSAction } from '../error/HMSAction';
import { HMSException } from '../error/HMSException';
import { EventBus } from '../events/EventBus';
import {
HMSAudioCodec,
HMSChangeMultiTrackStateParams,
HMSConfig,
HMSConnectionQualityListener,
Expand All @@ -37,6 +38,7 @@ import {
HMSRole,
HMSRoleChangeRequest,
HMSScreenShareConfig,
HMSVideoCodec,
TokenRequest,
TokenRequestOptions,
} from '../interfaces';
Expand All @@ -51,6 +53,7 @@ import { RTMPRecordingConfig } from '../interfaces/rtmp-recording-config';
import InitialSettings from '../interfaces/settings';
import { HMSAudioListener, HMSPeerUpdate, HMSTrackUpdate, HMSUpdateListener } from '../interfaces/update-listener';
import { PlaylistManager, TranscriptionConfig } from '../internal';
import { HMSAudioTrackSettingsBuilder, HMSVideoTrackSettingsBuilder } from '../media/settings';
import { HMSLocalStream } from '../media/streams/HMSLocalStream';
import {
HMSLocalAudioTrack,
Expand Down Expand Up @@ -95,7 +98,7 @@ import HMSLogger, { HMSLogLevel } from '../utils/logger';
import { HMSAudioContextHandler } from '../utils/media';
import { isNode } from '../utils/support';
import { workerSleep } from '../utils/timer-utils';
import { validateMediaDevicesExistence, validateRTCPeerConnection } from '../utils/validations';
import { validateMediaDevicesExistence, validatePublishParams, validateRTCPeerConnection } from '../utils/validations';

const INITIAL_STATE = {
published: false,
Expand Down Expand Up @@ -954,7 +957,8 @@ export class HMSSdk implements HMSInterface {

const TrackKlass = type === 'audio' ? HMSLocalAudioTrack : HMSLocalVideoTrack;
const hmsTrack = new TrackKlass(stream, track, source, this.eventBus);
this.setPlaylistSettings({
await this.applySettings(hmsTrack);
await this.setPlaylistSettings({
track,
hmsTrack,
source,
Expand Down Expand Up @@ -1603,4 +1607,42 @@ export class HMSSdk implements HMSInterface {
this.playlistManager.stop(HMSPlaylistType.video);
}
}

// eslint-disable-next-line complexity
private async applySettings(track: HMSLocalTrack) {
validatePublishParams(this.store);
const publishParams = this.store.getPublishParams();
// this is not needed but added for avoiding ? later
if (!publishParams) {
return;
}
if (track instanceof HMSLocalVideoTrack) {
const publishKey = track.source === 'regular' ? 'video' : track.source === 'screen' ? 'screen' : '';
if (!publishKey || !publishParams.allowed.includes(publishKey)) {
return;
}
const video = publishParams[publishKey];
if (!video) {
return;
}
const settings = new HMSVideoTrackSettingsBuilder()
.codec(video.codec as HMSVideoCodec)
.maxBitrate(video.bitRate)
.maxFramerate(video.frameRate)
.setWidth(video.width)
.setHeight(video.height)
.build();

await track.setSettings(settings);
} else if (track instanceof HMSLocalAudioTrack) {
if (!publishParams.allowed.includes('audio')) {
return;
}
const settings = new HMSAudioTrackSettingsBuilder()
.codec(publishParams.audio.codec as HMSAudioCodec)
.maxBitrate(publishParams.audio.bitRate)
.build();
await track.setSettings(settings);
}
}
}
45 changes: 24 additions & 21 deletions packages/hms-video-store/src/transport/RetryScheduler.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Dependencies as TFCDependencies, TransportFailureCategory as TFC } from './models/TransportFailureCategory';
import { TransportState } from './models/TransportState';
import { HMSException } from '../error/HMSException';
import { MAX_TRANSPORT_RETRIES, MAX_TRANSPORT_RETRY_DELAY } from '../utils/constants';
import { MAX_TRANSPORT_RETRY_TIME } from '../utils/constants';
import HMSLogger from '../utils/logger';
import { PromiseWithCallbacks } from '../utils/promise';

Expand All @@ -23,7 +23,7 @@ interface ScheduleTaskParams {
error: HMSException;
task: RetryTask;
originalState: TransportState;
maxFailedRetries?: number;
maxRetryTime?: number;
changeState?: boolean;
}

Expand All @@ -42,10 +42,10 @@ export class RetryScheduler {
error,
task,
originalState,
maxFailedRetries = MAX_TRANSPORT_RETRIES,
maxRetryTime = MAX_TRANSPORT_RETRY_TIME,
changeState = true,
}: ScheduleTaskParams) {
await this.scheduleTask({ category, error, changeState, task, originalState, maxFailedRetries });
await this.scheduleTask({ category, error, changeState, task, originalState, maxRetryTime, failedAt: Date.now() });
}

reset() {
Expand All @@ -65,9 +65,10 @@ export class RetryScheduler {
changeState,
task,
originalState,
maxFailedRetries = MAX_TRANSPORT_RETRIES,
failedAt,
maxRetryTime = MAX_TRANSPORT_RETRY_TIME,
failedRetryCount = 0,
}: ScheduleTaskParams & { failedRetryCount?: number }): Promise<void> {
}: ScheduleTaskParams & { failedAt: number; failedRetryCount?: number }): Promise<void> {
HMSLogger.d(this.TAG, 'schedule: ', { category: TFC[category], error });

// First schedule call
Expand Down Expand Up @@ -113,8 +114,9 @@ export class RetryScheduler {
}
}

if (failedRetryCount >= maxFailedRetries || hasFailedDependency) {
error.description += `. [${TFC[category]}] Could not recover after ${failedRetryCount} tries`;
const timeElapsedSinceError = Date.now() - failedAt;
if (timeElapsedSinceError >= maxRetryTime || hasFailedDependency) {
error.description += `. [${TFC[category]}] Could not recover after ${timeElapsedSinceError} milliseconds`;

if (hasFailedDependency) {
error.description += ` Could not recover all of it's required dependencies - [${(dependencies as Array<TFC>)
Expand Down Expand Up @@ -144,7 +146,7 @@ export class RetryScheduler {
this.onStateChange(TransportState.Reconnecting, error);
}

const delay = this.getDelayForRetryCount(category, failedRetryCount);
const delay = this.getDelayForRetryCount(category);

HMSLogger.d(
this.TAG,
Expand All @@ -171,33 +173,34 @@ export class RetryScheduler {
if (changeState && this.inProgress.size === 0) {
this.onStateChange(originalState);
}
HMSLogger.d(this.TAG, `schedule: [${TFC[category]}] [failedRetryCount=${failedRetryCount}] Recovered ♻️`);
HMSLogger.d(
this.TAG,
`schedule: [${TFC[category]}] [failedRetryCount=${failedRetryCount}] Recovered ♻️ after ${timeElapsedSinceError}ms`,
);
} else {
await this.scheduleTask({
category,
error,
changeState,
task,
originalState,
maxFailedRetries,
maxRetryTime,
failedAt,
failedRetryCount: failedRetryCount + 1,
});
}
}

private getBaseDelayForTask(category: TFC, n: number) {
private getDelayForRetryCount(category: TFC) {
const jitter = category === TFC.JoinWSMessageFailed ? Math.random() * 2 : Math.random();
let delaySeconds = 0;
if (category === TFC.JoinWSMessageFailed) {
// linear backoff(2 + jitter for every retry)
return 2;
delaySeconds = 2 + jitter;
} else if (category === TFC.SignalDisconnect) {
delaySeconds = 1;
}
// exponential backoff
return Math.pow(2, n);
}

private getDelayForRetryCount(category: TFC, n: number) {
const delay = this.getBaseDelayForTask(category, n);
const jitter = category === TFC.JoinWSMessageFailed ? Math.random() * 2 : Math.random();
return Math.round(Math.min(delay + jitter, MAX_TRANSPORT_RETRY_DELAY) * 1000);
return delaySeconds * 1000;
}

private async setTimeoutPromise<T>(task: () => Promise<T>, delay: number): Promise<T> {
Expand Down
4 changes: 0 additions & 4 deletions packages/hms-video-store/src/transport/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import { ISignalEventsObserver } from '../signal/ISignalEventsObserver';
import JsonRpcSignal from '../signal/jsonrpc';
import {
ICE_DISCONNECTION_TIMEOUT,
MAX_TRANSPORT_RETRIES,
PROTOCOL_SPEC,
PROTOCOL_VERSION,
PUBLISH_STATS_PUSH_INTERVAL,
Expand Down Expand Up @@ -352,7 +351,6 @@ export default class HMSTransport {
error,
task,
originalState: this.state,
maxFailedRetries: MAX_TRANSPORT_RETRIES,
changeState: false,
});
} else {
Expand Down Expand Up @@ -923,7 +921,6 @@ export default class HMSTransport {
error: hmsError,
task,
originalState: TransportState.Joined,
maxFailedRetries: 3,
changeState: false,
});
} else {
Expand Down Expand Up @@ -1087,7 +1084,6 @@ export default class HMSTransport {
error,
task: this.retrySubscribeIceFailedTask,
originalState: TransportState.Joined,
maxFailedRetries: 1,
});
}
}
Expand Down
5 changes: 2 additions & 3 deletions packages/hms-video-store/src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ export const API_DATA_CHANNEL = 'ion-sfu';
export const ANALYTICS_BUFFER_SIZE = 100;

/**
* Maximum number of retries that transport-layer will try
* Maximum time that transport-layer will try
* before giving up on the connection and returning a failure
*
* Refer https://100ms.atlassian.net/browse/HMS-2369
*/
export const MAX_TRANSPORT_RETRIES = 5;
export const MAX_TRANSPORT_RETRY_DELAY = 60;
export const MAX_TRANSPORT_RETRY_TIME = 60_000;

export const DEFAULT_SIGNAL_PING_TIMEOUT = 12_000;
export const DEFAULT_SIGNAL_PING_INTERVAL = 3_000;
Expand Down
12 changes: 12 additions & 0 deletions packages/hms-video-store/src/utils/validations.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import HMSLogger from './logger';
import { ErrorFactory } from '../error/ErrorFactory';
import { HMSAction } from '../error/HMSAction';
import { Store } from '../sdk/store';

const TAG = `[VALIDATIONS]`;

Expand Down Expand Up @@ -32,3 +34,13 @@ export const validateMediaDevicesExistence = () => {
throw error;
}
};

export const validatePublishParams = (store: Store) => {
const publishParams = store.getPublishParams();
if (!publishParams) {
throw ErrorFactory.GenericErrors.NotConnected(
HMSAction.VALIDATION,
'call addTrack after preview or join is successful',
);
}
};

0 comments on commit 4e6a405

Please sign in to comment.