Skip to content

Commit

Permalink
refactor with ServerTimeSync
Browse files Browse the repository at this point in the history
Signed-off-by: Timo K <[email protected]>
  • Loading branch information
toger5 committed Jan 29, 2024
1 parent 348c37f commit 05de2f0
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 11 deletions.
15 changes: 6 additions & 9 deletions src/matrixrtc/CallMembership.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ limitations under the License.
*/

import { MatrixEvent } from "../matrix";
import * as ServeTimeSync from "../server-time-sync";
import { deepCompare } from "../utils";
import { Focus } from "./focus";

Expand Down Expand Up @@ -101,16 +102,12 @@ export class CallMembership {

// gets the expiry time of the event, converted into the device's local time
public getLocalExpiry(): number {
if (this.data.expires_ts) {
// With expires_ts we cannot convert to local time.
// TODO: Check the server timestamp and compute a diff to local time.
return this.data.expires_ts;
ServeTimeSync.tryComputeTimeSyncWithEvent(this.parentEvent);
if (this.data.expires) {
return ServeTimeSync.serverTsToLocalTs(this.createdTs()) + this.data.expires!;
} else {
const relativeCreationTime = this.parentEvent.getTs() - this.createdTs();

const localCreationTs = this.parentEvent.localTimestamp - relativeCreationTime;

return localCreationTs + this.data.expires!;
// We know it exists because we checked for this in the constructor.
return ServeTimeSync.serverTsToLocalTs(this.data.expires_ts!);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/matrixrtc/MatrixRTCSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { MatrixError, MatrixEvent } from "../matrix";
import { randomString, secureRandomBase64Url } from "../randomstring";
import { EncryptionKeysEventContent } from "./types";
import { decodeBase64, encodeUnpaddedBase64 } from "../base64";
import * as ServerTimeSync from "../server-time-sync";

const MEMBERSHIP_EXPIRY_TIME = 60 * 60 * 1000;
const MEMBER_EVENT_CHECK_PERIOD = 2 * 60 * 1000; // How often we check to see if we need to re-send our member event
Expand Down Expand Up @@ -625,8 +626,7 @@ export class MatrixRTCSession extends TypedEventEmitter<MatrixRTCSessionEvent, M

if (prevMembership) m.created_ts = prevMembership.createdTs();
if (m.created_ts) m.expires_ts = m.created_ts + (m.expires ?? 0);
// TODO: Date.now() should be the origin_server_ts (now).
else m.expires_ts = Date.now() + (m.expires ?? 0);
else m.expires_ts = ServerTimeSync.getServerTimeNow() + (m.expires ?? 0);

return m;
}
Expand Down
83 changes: 83 additions & 0 deletions src/server-time-sync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { logger } from "./logger";
import { MatrixEvent } from "./matrix";

/*
Copyright 2021-2024 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
let serverToLocalTimeOffset: number | undefined = undefined;

/**
* This method should only be used after computing the server-client time offset
* using: tryComputeTimeSyncWithEvent or computeTimeSyncWithRequest.
*/
const getServerToLocalTimeOffset = (): number => {
if (!serverToLocalTimeOffset) {
logger.warn("Server time offset not computed yet, using 0");
serverToLocalTimeOffset = 0;
}
if (!serverToLocalTimeOffset) throw new Error("Failed to compute time sync");

return serverToLocalTimeOffset;
};
/**
* This uses a matrix event with an age property to compute the time offset.
* This also works when the event was not just now received from the homeserver
* because the event tracks the time since it has been received via the localTimestamp.
* @param event - The matrix event used to compute the time offset.
* @returns true if the time offset computation was successful, false otherwise
*/
export const tryComputeTimeSyncWithEvent = (event: MatrixEvent): boolean => {
const serverTimeNow = event.getTs() + event.getLocalAge();

Check failure on line 42 in src/server-time-sync.ts

View workflow job for this annotation

GitHub Actions / Jest [unit] (Node 18)

CallMembership › considers memberships expired when local age large

TypeError: event.getLocalAge is not a function at Object.getLocalAge [as tryComputeTimeSyncWithEvent] (src/server-time-sync.ts:42:49) at CallMembership.tryComputeTimeSyncWithEvent [as getLocalExpiry] (src/matrixrtc/CallMembership.ts:105:23) at CallMembership.getLocalExpiry [as getMsUntilExpiry] (src/matrixrtc/CallMembership.ts:115:21) at CallMembership.getMsUntilExpiry [as isExpired] (src/matrixrtc/CallMembership.ts:119:21) at Object.isExpired (spec/unit/matrixrtc/CallMembership.spec.ts:111:27)

Check failure on line 42 in src/server-time-sync.ts

View workflow job for this annotation

GitHub Actions / Jest [unit] (Node lts/*)

CallMembership › considers memberships expired when local age large

TypeError: event.getLocalAge is not a function at Object.getLocalAge [as tryComputeTimeSyncWithEvent] (src/server-time-sync.ts:42:49) at CallMembership.tryComputeTimeSyncWithEvent [as getLocalExpiry] (src/matrixrtc/CallMembership.ts:105:23) at CallMembership.getLocalExpiry [as getMsUntilExpiry] (src/matrixrtc/CallMembership.ts:115:21) at CallMembership.getMsUntilExpiry [as isExpired] (src/matrixrtc/CallMembership.ts:119:21) at Object.isExpired (spec/unit/matrixrtc/CallMembership.spec.ts:111:27)

Check failure on line 42 in src/server-time-sync.ts

View workflow job for this annotation

GitHub Actions / Jest [unit] (Node 21)

CallMembership › considers memberships expired when local age large

TypeError: event.getLocalAge is not a function at Object.getLocalAge [as tryComputeTimeSyncWithEvent] (src/server-time-sync.ts:42:49) at CallMembership.tryComputeTimeSyncWithEvent [as getLocalExpiry] (src/matrixrtc/CallMembership.ts:105:23) at CallMembership.getLocalExpiry [as getMsUntilExpiry] (src/matrixrtc/CallMembership.ts:115:21) at CallMembership.getMsUntilExpiry [as isExpired] (src/matrixrtc/CallMembership.ts:119:21) at Object.isExpired (spec/unit/matrixrtc/CallMembership.spec.ts:111:27)
serverToLocalTimeOffset = serverTimeNow - Date.now();

return true;
};

/**
* Computes the time offset between the server and the local machine by sending
* a http request to the server.
* (UNIMPLEMNENTED)
* @returns true if the time offset computation was successful, false otherwise
*/
export const computeTimeSyncWithRequest = async (): Promise<boolean> => {
// TODO: fetch time now from server (temporarily use offset of 0)
serverToLocalTimeOffset = 0;
return true;
// await ...
};

/**
* This method should only be used after computing the server-client time offset
* using: tryComputeTimeSyncWithEvent or computeTimeSyncWithRequest.
*/
export const getServerTimeNow = (): number => {
return localTsToServerTs(Date.now());
};

/**
* This method should only be used after computing the server-client time offset
* using: tryComputeTimeSyncWithEvent or computeTimeSyncWithRequest.
*/
export const serverTsToLocalTs = (serverTs: number): number => {
return serverTs + getServerToLocalTimeOffset();
};

/**
* This method should only be used after computing the server-client time offset
* using: tryComputeTimeSyncWithEvent or computeTimeSyncWithRequest.
*/
export const localTsToServerTs = (localTs: number): number => {
return localTs - getServerToLocalTimeOffset();
};

0 comments on commit 05de2f0

Please sign in to comment.