Skip to content

Commit

Permalink
update replayclient
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonLaster committed Sep 24, 2024
1 parent db053e2 commit cfb2420
Showing 1 changed file with 34 additions and 116 deletions.
150 changes: 34 additions & 116 deletions packages/shared/client/ReplayClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,21 +77,8 @@ import throttle from "lodash/throttle";
import uniqueId from "lodash/uniqueId";

// eslint-disable-next-line no-restricted-imports
import {
addEventListener,
client,
initSocket,
removeEventListener,
sendMessage,
} from "protocol/socket";
import {
assert,
breakdownSupplementalId,
compareExecutionPoints,
defer,
transformSupplementalId,
waitForTime,
} from "protocol/utils";
import { addEventListener, client, initSocket, sendMessage, removeEventListener } from "protocol/socket";
import { assert, compareExecutionPoints, defer, waitForTime, transformSupplementalId, breakdownSupplementalId } from "protocol/utils";
import { initProtocolMessagesStore } from "replay-next/components/protocol/ProtocolMessagesStore";
import { insert } from "replay-next/src/utils/array";
import { TOO_MANY_POINTS_TO_FIND } from "shared/constants";
Expand Down Expand Up @@ -152,11 +139,7 @@ export class ReplayClient implements ReplayClientInterface {
// Configures the client to use an already initialized session iD.
// This method should be used for apps that use the protocol package directly.
// Apps that only communicate with the Replay protocol through this client should use the initialize method instead.
async configure(
recordingId: string,
sessionId: string,
supplemental: SupplementalSession[]
): Promise<void> {
async configure(recordingId: string, sessionId: string, supplemental: SupplementalSession[]): Promise<void> {
this._recordingId = recordingId;
this._sessionId = sessionId;
this._dispatchEvent("sessionCreated");
Expand All @@ -182,9 +165,7 @@ export class ReplayClient implements ReplayClientInterface {
return this.supplemental.length;
}

private async forEachSession(
callback: (sessionId: string, supplementalIndex: number) => Promise<void>
) {
private async forEachSession(callback: (sessionId: string, supplementalIndex: number) => Promise<void>) {
const sessionId = await this.waitForSession();
await callback(sessionId, 0);
for (let i = 0; i < this.supplemental.length; i++) {
Expand All @@ -201,17 +182,15 @@ export class ReplayClient implements ReplayClientInterface {
return supplementalInfo.sessionId;
}

private async breakdownSupplementalIdAndSession(
transformedId: string
): Promise<{ id: string; sessionId: string; supplementalIndex: number }> {
private async breakdownSupplementalIdAndSession(transformedId: string): Promise<{ id: string, sessionId: string, supplementalIndex: number }> {
const { id, supplementalIndex } = breakdownSupplementalId(transformedId);
const sessionId = await this.getSupplementalIndexSession(supplementalIndex);
return { id, sessionId, supplementalIndex };
}

private async getPauseSessionId(pauseId: string): Promise<string> {
const sessionId = this.pauseIdToSessionId.get(pauseId);
return sessionId || (await this.waitForSession());
return sessionId || await this.waitForSession();
}

private getSessionIdSupplementalIndex(sessionId: string) {
Expand Down Expand Up @@ -243,9 +222,7 @@ export class ReplayClient implements ReplayClientInterface {
}

async createPause(transformedExecutionPoint: ExecutionPoint): Promise<createPauseResult> {
const { id: executionPoint, sessionId } = await this.breakdownSupplementalIdAndSession(
transformedExecutionPoint
);
const { id: executionPoint, sessionId } = await this.breakdownSupplementalIdAndSession(transformedExecutionPoint);

await this.waitForPointToBeInFocusRange(executionPoint);

Expand Down Expand Up @@ -600,13 +577,11 @@ export class ReplayClient implements ReplayClientInterface {
transformedPointSelector: PointSelector,
pointLimits?: PointPageLimits
): Promise<PointDescription[]> {
const { pointSelector, sessionId } = await this.breakdownSupplementalPointSelector(
transformedPointSelector
);
const { pointSelector, sessionId } = await this.breakdownSupplementalPointSelector(transformedPointSelector);

const points: PointDescription[] = [];
const findPointsId = String(this.nextFindPointsId++);
pointLimits = pointLimits && this.isMainSession(sessionId) ? { ...pointLimits } : {};
pointLimits = (pointLimits && this.isMainSession(sessionId)) ? { ...pointLimits } : {};
if (!pointLimits.maxCount) {
pointLimits.maxCount = MAX_POINTS_TO_FIND;
}
Expand Down Expand Up @@ -652,21 +627,17 @@ export class ReplayClient implements ReplayClientInterface {
return this.supplemental[supplementalIndex - 1].serverRecordingId;
}

private forAllConnections(
callback: (
serverRecordingId: string,
connection: SupplementalRecordingConnection,
supplementalIndex: number
) => void
) {
private forAllConnections(callback: (serverRecordingId: string, connection: SupplementalRecordingConnection, supplementalIndex: number) => void) {
this.supplemental.forEach(({ serverRecordingId, connections }, i) => {
for (const connection of connections) {
callback(serverRecordingId, connection, i + 1);
}
});
}

getTargetPoint(point: ExecutionPoint, pointSupplementalIndex: number): TargetPoint | null {
getTargetPoint(point: ExecutionPoint, pointSupplementalIndex: number): {
point: TimeStampedPoint, supplementalIndex: number
} | null {
const recordingId = this.getSupplementalIndexRecordingId(pointSupplementalIndex);

let targetPoint: TimeStampedPoint | undefined;
Expand Down Expand Up @@ -694,22 +665,16 @@ export class ReplayClient implements ReplayClientInterface {
return { point: targetPoint, supplementalIndex: targetSupplementalIndex };
}

private async maybeGetConnectionStepTarget(
point: ExecutionPoint,
pointSupplementalIndex: number
): Promise<PauseDescription | null> {
private async maybeGetConnectionStepTarget(point: ExecutionPoint, pointSupplementalIndex: number): Promise<PauseDescription | null> {

const targetPoint = this.getTargetPoint(point, pointSupplementalIndex);
if (!targetPoint) {
return null;
}

const sessionId = await this.getSupplementalIndexSession(targetPoint.supplementalIndex);

const response = await sendMessage(
"Session.getPointFrameSteps" as any,
{ point: targetPoint.point },
sessionId
);
const response = await sendMessage("Session.getPointFrameSteps" as any, { point: targetPoint.point }, sessionId);
const { steps } = response;
const desc = steps.find((step: PointDescription) => step.point == targetPoint.point?.point);
assert(desc);
Expand All @@ -719,11 +684,7 @@ export class ReplayClient implements ReplayClientInterface {
}

async findStepInTarget(transformedPoint: ExecutionPoint): Promise<PauseDescription> {
const {
id: point,
sessionId,
supplementalIndex,
} = await this.breakdownSupplementalIdAndSession(transformedPoint);
const { id: point, sessionId, supplementalIndex } = await this.breakdownSupplementalIdAndSession(transformedPoint);
const connectionStepTarget = await this.maybeGetConnectionStepTarget(point, supplementalIndex);
if (connectionStepTarget) {
return connectionStepTarget;
Expand Down Expand Up @@ -765,9 +726,7 @@ export class ReplayClient implements ReplayClientInterface {
for (const source of sourcesList) {
if (supplementalIndex) {
source.sourceId = transformSupplementalId(source.sourceId, supplementalIndex);
source.generatedSourceIds = source.generatedSourceIds?.map(id =>
transformSupplementalId(id, supplementalIndex)
);
source.generatedSourceIds = source.generatedSourceIds?.map(id => transformSupplementalId(id, supplementalIndex));
}
sources.push(source);
}
Expand All @@ -787,10 +746,7 @@ export class ReplayClient implements ReplayClientInterface {
location.sourceId = transformSupplementalId(location.sourceId, supplementalIndex);
}

private transformSupplementalMappedLocation(
mappedLocation: MappedLocation | undefined,
supplementalIndex: number
) {
private transformSupplementalMappedLocation(mappedLocation: MappedLocation | undefined, supplementalIndex: number) {
for (const location of mappedLocation || []) {
this.transformSupplementalLocation(location, supplementalIndex);
}
Expand Down Expand Up @@ -843,10 +799,7 @@ export class ReplayClient implements ReplayClientInterface {
return result;
}

async getPointStack(
transformedPoint: ExecutionPoint,
maxCount: number
): Promise<PointStackFrame[]> {
async getPointStack(transformedPoint: ExecutionPoint, maxCount: number): Promise<PointStackFrame[]> {
const { id: point, sessionId } = await this.breakdownSupplementalIdAndSession(transformedPoint);
const result = await client.Session.getPointStack({ point, maxCount }, sessionId);
return result.frames;
Expand Down Expand Up @@ -1096,10 +1049,7 @@ export class ReplayClient implements ReplayClientInterface {
return screen;
}

async mapExpressionToGeneratedScope(
expression: string,
transformedLocation: Location
): Promise<string> {
async mapExpressionToGeneratedScope(expression: string, transformedLocation: Location): Promise<string> {
const { location, sessionId } = await this.breakdownSupplementalLocation(transformedLocation);
const result = await client.Debugger.mapExpressionToGeneratedScope(
{ expression, location },
Expand All @@ -1121,37 +1071,26 @@ export class ReplayClient implements ReplayClientInterface {
locations: SameLineSourceLocations[],
focusRange: PointRange | null
) {
const { id: sourceId, sessionId } = await this.breakdownSupplementalIdAndSession(
transformedSourceId
);
const { id: sourceId, sessionId } = await this.breakdownSupplementalIdAndSession(transformedSourceId);

await this.waitForRangeToBeInFocusRange(focusRange);
const { hits } = await client.Debugger.getHitCounts(
{
sourceId,
locations,
maxHits: TOO_MANY_POINTS_TO_FIND,
range: (this.isMainSession(sessionId) && focusRange) || undefined,
},
{ sourceId, locations, maxHits: TOO_MANY_POINTS_TO_FIND, range: (this.isMainSession(sessionId) && focusRange) || undefined },
sessionId
);
return hits;
}

async getSourceOutline(transformedSourceId: SourceId) {
const { id: sourceId, sessionId } = await this.breakdownSupplementalIdAndSession(
transformedSourceId
);
const { id: sourceId, sessionId } = await this.breakdownSupplementalIdAndSession(transformedSourceId);
return client.Debugger.getSourceOutline({ sourceId }, sessionId);
}

async getBreakpointPositions(
transformedSourceId: SourceId,
locationRange: SourceLocationRange | null
): Promise<SameLineSourceLocations[]> {
const { id: sourceId, sessionId } = await this.breakdownSupplementalIdAndSession(
transformedSourceId
);
const { id: sourceId, sessionId } = await this.breakdownSupplementalIdAndSession(transformedSourceId);

const begin = locationRange ? locationRange.start : undefined;
const end = locationRange ? locationRange.end : undefined;
Expand Down Expand Up @@ -1351,11 +1290,9 @@ export class ReplayClient implements ReplayClientInterface {
},
onResults: (results: RunEvaluationResult[]) => void
): Promise<void> {
const { pointSelector, sessionId, supplementalIndex } =
await this.breakdownSupplementalPointSelector(opts.selector);
const { pointSelector, sessionId, supplementalIndex } = await this.breakdownSupplementalPointSelector(opts.selector);
const runEvaluationId = String(this.nextRunEvaluationId++);
const pointLimits: PointPageLimits =
opts.limits && !supplementalIndex ? { ...opts.limits } : {};
const pointLimits: PointPageLimits = (opts.limits && !supplementalIndex) ? { ...opts.limits } : {};
if (!pointLimits.maxCount) {
pointLimits.maxCount = MAX_POINTS_TO_RUN_EVALUATION;
}
Expand Down Expand Up @@ -1407,9 +1344,7 @@ export class ReplayClient implements ReplayClientInterface {
onSourceContentsInfo: (params: sourceContentsInfo) => void,
onSourceContentsChunk: (params: sourceContentsChunk) => void
): Promise<void> {
const { id: sourceId, sessionId } = await this.breakdownSupplementalIdAndSession(
transformedSourceId
);
const { id: sourceId, sessionId } = await this.breakdownSupplementalIdAndSession(transformedSourceId);

let pendingChunk = "";
let pendingThrottlePromise: Promise<void> | null = null;
Expand Down Expand Up @@ -1571,10 +1506,7 @@ function waitForOpenConnection(
//
// If there is no such delta then we're seeing inconsistent timing information with
// the connections and will fall back onto interpolateSupplementalTime.
function computeSupplementalTimeDelta(
recordingId: string,
supplemental: SupplementalSession
): number | undefined {
function computeSupplementalTimeDelta(recordingId: string, supplemental: SupplementalSession): number | undefined {
// Delta which ensures that all clientFirst connections happen
// on the client before they happen on the server.
let clientFirstDelta: number | undefined;
Expand All @@ -1583,12 +1515,7 @@ function computeSupplementalTimeDelta(
// on the server before they happen on the client.
let clientLastDelta: number | undefined;

for (const {
clientFirst,
clientRecordingId,
clientPoint,
serverPoint,
} of supplemental.connections) {
for (const { clientFirst, clientRecordingId, clientPoint, serverPoint } of supplemental.connections) {
assert(recordingId == clientRecordingId);
const delta = serverPoint.time - clientPoint.time;
if (clientFirst) {
Expand Down Expand Up @@ -1617,10 +1544,7 @@ function computeSupplementalTimeDelta(
// client events in the connection actually happen before the server
// event on the timeline instead of at the exact same time, which can
// cause console messages to be rendered in the wrong order.
function adjustInterpolateSupplementalTime(
connection: SupplementalRecordingConnection,
clientTime: number
) {
function adjustInterpolateSupplementalTime(connection: SupplementalRecordingConnection, clientTime: number) {
const { clientFirst, clientPoint } = connection;
const Epsilon = 0.1;
if (clientFirst) {
Expand All @@ -1641,11 +1565,7 @@ function adjustInterpolateSupplementalTime(
// This works even if there is no single consistent delta to use throughout the
// recording, and requires that events on either side of the connections happen
// in the same order in the two recordings.
function interpolateSupplementalTime(
recordingId: string,
supplemental: SupplementalSession,
supplementalTime: number
): number {
function interpolateSupplementalTime(recordingId: string, supplemental: SupplementalSession, supplementalTime: number): number {
assert(supplemental.connections.length);
for (const connection of supplemental.connections) {
assert(connection.clientRecordingId == recordingId);
Expand All @@ -1657,10 +1577,8 @@ function interpolateSupplementalTime(
const next = supplemental.connections[i];
assert(previous.clientPoint.time <= next.clientPoint.time);
assert(previous.serverPoint.time <= next.serverPoint.time);
if (
supplementalTime >= previous.serverPoint.time &&
supplementalTime <= next.serverPoint.time
) {
if (supplementalTime >= previous.serverPoint.time &&
supplementalTime <= next.serverPoint.time) {
const clientElapsed = next.clientPoint.time - previous.clientPoint.time;
const serverElapsed = next.serverPoint.time - previous.serverPoint.time;
const fraction = (supplementalTime - previous.serverPoint.time) / serverElapsed;
Expand Down

0 comments on commit cfb2420

Please sign in to comment.