Call debugging

This commit is contained in:
Isaac 2025-04-23 12:20:11 +04:00
parent da2849dfcf
commit 9b0bcee0a7
4 changed files with 69 additions and 7 deletions

View File

@ -336,6 +336,15 @@ private final class ConferenceCallE2EContextStateImpl: ConferenceCallE2EContextS
return self.call.participants().map { ConferenceCallE2EContext.BlockchainParticipant(userId: $0.userId, internalId: $0.internalId) }
}
func getParticipantLatencies() -> [Int64: Double] {
let dict = self.call.participantLatencies()
var result: [Int64: Double] = [:]
for (k, v) in dict {
result[k.int64Value] = v.doubleValue
}
return result
}
func getParticipantIds() -> [Int64] {
return self.call.participants().map { $0.userId }
}

View File

@ -5,6 +5,7 @@ public protocol ConferenceCallE2EContextState: AnyObject {
func getEmojiState() -> Data?
func getParticipantIds() -> [Int64]
func getParticipants() -> [ConferenceCallE2EContext.BlockchainParticipant]
func getParticipantLatencies() -> [Int64: Double]
func applyBlock(block: Data)
func applyBroadcastBlock(block: Data)
@ -166,7 +167,7 @@ public final class ConferenceCallE2EContext {
let keyPair = self.keyPair
let userId = self.userId
let initializeState = self.initializeState
let (outBlocks, outEmoji, outBlockchainParticipants) = self.state.with({ callState -> ([Data], Data, [BlockchainParticipant]) in
let (outBlocks, outEmoji, outBlockchainParticipants, participantLatencies) = self.state.with({ callState -> ([Data], Data, [BlockchainParticipant], [Int64: Double]) in
if let state = callState.state {
for block in blocks {
if subChainId == 0 {
@ -175,26 +176,26 @@ public final class ConferenceCallE2EContext {
state.applyBroadcastBlock(block: block)
}
}
return (state.takeOutgoingBroadcastBlocks(), state.getEmojiState() ?? Data(), state.getParticipants())
return (state.takeOutgoingBroadcastBlocks(), state.getEmojiState() ?? Data(), state.getParticipants(), state.getParticipantLatencies())
} else {
if subChainId == 0 {
guard let block = blocks.last else {
return ([], Data(), [])
return ([], Data(), [], [:])
}
guard let state = initializeState(keyPair, userId, block) else {
return ([], Data(), [])
return ([], Data(), [], [:])
}
callState.state = state
for block in callState.pendingIncomingBroadcastBlocks {
state.applyBroadcastBlock(block: block)
}
callState.pendingIncomingBroadcastBlocks.removeAll()
return (state.takeOutgoingBroadcastBlocks(), state.getEmojiState() ?? Data(), state.getParticipants())
return (state.takeOutgoingBroadcastBlocks(), state.getEmojiState() ?? Data(), state.getParticipants(), state.getParticipantLatencies())
} else if subChainId == 1 {
callState.pendingIncomingBroadcastBlocks.append(contentsOf: blocks)
return ([], Data(), [])
return ([], Data(), [], [:])
} else {
return ([], Data(), [])
return ([], Data(), [], [:])
}
}
})
@ -204,6 +205,10 @@ public final class ConferenceCallE2EContext {
for outBlock in outBlocks {
let _ = self.engine.calls.sendConferenceCallBroadcast(callId: self.callId, accessHash: self.accessHash, block: outBlock).startStandalone()
}
#if DEBUG
print("Latencies: \(participantLatencies)")
#endif
}
private func e2ePoll(subChainId: Int) {

View File

@ -37,6 +37,8 @@ NS_ASSUME_NONNULL_BEGIN
- (NSData *)emojiState;
- (NSArray<TdCallParticipant *> *)participants;
- (NSDictionary<NSNumber *, NSNumber *> *)participantLatencies;
- (void)applyBlock:(NSData *)block;
- (void)applyBroadcastBlock:(NSData *)block;

View File

@ -190,6 +190,52 @@ static NSString *hexStringFromData(NSData *data) {
return participants;
}
- (NSDictionary<NSNumber *, NSNumber *> *)participantLatencies {
auto describeResult = tde2e_api::call_describe(_callId);
if (describeResult.is_ok()) {
NSString *string = [[NSString alloc] initWithData:[NSData dataWithBytes:describeResult.value().data() length:describeResult.value().size()] encoding:NSASCIIStringEncoding];
NSRegularExpression *pairRe = [NSRegularExpression regularExpressionWithPattern:@"(\\d+):(\\d+\\.\\d+)s" options:0 error:NULL];
NSMutableDictionary<NSNumber*, NSNumber*> *commitTimes = [NSMutableDictionary dictionary];
NSMutableDictionary<NSNumber*, NSNumber*> *revealTimes = [NSMutableDictionary dictionary];
// split into lines and look for the two lines
[string enumerateLinesUsingBlock:^(NSString * _Nonnull line, BOOL * _Nonnull stop) {
if ([line containsString:@"commit ="]) {
[pairRe enumerateMatchesInString:line options:0 range:NSMakeRange(0, line.length) usingBlock:^(NSTextCheckingResult * _Nullable match, NSMatchingFlags flags, BOOL * _Nonnull stop) {
NSString *userIdStr = [line substringWithRange:[match rangeAtIndex:1]];
NSString *durStr = [line substringWithRange:[match rangeAtIndex:2]];
NSNumber *uid = @([userIdStr longLongValue]);
NSNumber *dur = @([durStr doubleValue]);
commitTimes[uid] = dur;
}];
}
else if ([line containsString:@"reveal ="]) {
[pairRe enumerateMatchesInString:line options:0 range:NSMakeRange(0, line.length) usingBlock:^(NSTextCheckingResult * _Nullable match, NSMatchingFlags flags, BOOL * _Nonnull stop) {
NSString *userIdStr = [line substringWithRange:[match rangeAtIndex:1]];
NSString *durStr = [line substringWithRange:[match rangeAtIndex:2]];
NSNumber *uid = @([userIdStr longLongValue]);
NSNumber *dur = @([durStr doubleValue]);
revealTimes[uid] = dur;
}];
}
}];
// build final result = commit+reveal
NSMutableDictionary<NSNumber*, NSNumber*> *result = [NSMutableDictionary dictionary];
for (NSNumber *uid in commitTimes) {
double commit = commitTimes[uid].doubleValue;
double reveal = revealTimes[uid].doubleValue; // will be 0 if missing
result[uid] = @(commit + reveal);
}
return result;
}
return @{};
}
- (void)applyBlock:(NSData *)block {
std::string mappedBlock((uint8_t *)block.bytes, ((uint8_t *)block.bytes) + block.length);