Skip to content

Commit 02b6a6d

Browse files
feat: track teleport op duration
1 parent df35da1 commit 02b6a6d

8 files changed

Lines changed: 49 additions & 19 deletions

File tree

Explorer/Assets/DCL/ApplicationGuards/ApplicationMinimumSpecsGuard/UI/MinimumSpecsScreenController.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ protected override void OnViewInstantiated()
4343

4444
protected override void OnViewShow()
4545
{
46-
analytics.Track(AnalyticsEvents.UI.MINIMUM_REQUIREMENTS_SCREEN_SHOWN);
46+
analytics.Track(AnalyticsEvents.Ui.MINIMUM_REQUIREMENTS_SCREEN_SHOWN);
4747
}
4848

4949
private void OnToggleChanged(bool dontShowAgain)
@@ -65,7 +65,7 @@ public override void Dispose()
6565
private void OnContinueClicked()
6666
{
6767
DCLPlayerPrefs.SetBool(DCLPrefKeys.DONT_SHOW_MIN_SPECS_SCREEN, viewInstance!.DontShowAgainToggle.isOn, true);
68-
analytics.Track(AnalyticsEvents.UI.SKIP_MINIMUM_REQUIREMENTS_SCREEN);
68+
analytics.Track(AnalyticsEvents.Ui.SKIP_MINIMUM_REQUIREMENTS_SCREEN);
6969
HoldingTask.TrySetResult();
7070
}
7171

Explorer/Assets/DCL/PerformanceAndDiagnostics/Analytics/AnalyticsEvents.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public static class General
1616
public const string ERROR = "error";
1717
public const string LOADING_ERROR = "loading_error";
1818
public const string MEETS_MINIMUM_REQUIREMENTS = "meets_minimum_requirements";
19+
public const string TELEPORT_OPERATION_DURATION = "teleport_operation_duration";
1920
}
2021

2122
public static class World
@@ -29,7 +30,7 @@ public static class Wearables
2930
public const string USED_EMOTE = "used_emote";
3031
}
3132

32-
public static class UI
33+
public static class Ui
3334
{
3435
public const string MESSAGE_SENT = "chat_message_sent";
3536
public const string BUBBLE_SWITCHED = "chat_bubble_switched";

Explorer/Assets/DCL/PerformanceAndDiagnostics/Analytics/DecoratorBased/ChatMessagesBusAnalyticsDecorator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public class ChatMessagesBusAnalyticsDecorator : IChatMessagesBus
1818
private readonly IProfileCache profileCache;
1919
private readonly SelfProfile selfProfile;
2020

21-
public event Action<ChatChannel.ChannelId, ChatChannel.ChatChannelType, ChatMessage> MessageAdded;
21+
public event Action<ChatChannel.ChannelId, ChatChannel.ChatChannelType, ChatMessage>? MessageAdded;
2222

2323
public ChatMessagesBusAnalyticsDecorator(IChatMessagesBus core, IAnalyticsController analytics, IProfileCache profileCache, SelfProfile selfProfile)
2424
{
@@ -64,7 +64,7 @@ public void Send(ChatChannel channel, string message, ChatMessageOrigin origin,
6464
if (channel.ChannelType == ChatChannel.ChatChannelType.COMMUNITY)
6565
jsonObject.Add("community_id", ChatChannel.GetCommunityIdFromChannelId(channel.Id));
6666

67-
analytics.Track(AnalyticsEvents.UI.MESSAGE_SENT, jsonObject);
67+
analytics.Track(AnalyticsEvents.Ui.MESSAGE_SENT, jsonObject);
6868
}
6969

7070
private bool CheckIfIsMention(string message)

Explorer/Assets/DCL/PerformanceAndDiagnostics/Analytics/EventBased/ChatAnalytics.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ public void Dispose()
2525
}
2626

2727
private void OnConversationClosed() =>
28-
analytics.Track(AnalyticsEvents.UI.CHAT_CONVERSATION_CLOSED);
28+
analytics.Track(AnalyticsEvents.Ui.CHAT_CONVERSATION_CLOSED);
2929

3030
private void OnConversationOpened(bool wasAlreadyOpen) =>
31-
analytics.Track(AnalyticsEvents.UI.CHAT_CONVERSATION_OPENED, new JObject
31+
analytics.Track(AnalyticsEvents.Ui.CHAT_CONVERSATION_OPENED, new JObject
3232
{
3333
{ "was_already_open", wasAlreadyOpen },
3434
});

Explorer/Assets/DCL/PerformanceAndDiagnostics/Analytics/EventBased/HomeMarkerAnalytics.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ private void OnHomeChanged(HomeMarkerEvents.MessageHomePositionChanged evt)
3232
{ "world_name", evt.WorldName ?? string.Empty }
3333
};
3434

35-
analytics.Track(AnalyticsEvents.UI.HOME_POSITION_SET, properties);
35+
analytics.Track(AnalyticsEvents.Ui.HOME_POSITION_SET, properties);
3636
}
3737

3838

Explorer/Assets/DCL/PerformanceAndDiagnostics/Analytics/EventBased/SupportAnalytics.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public void Dispose()
3030
}
3131

3232
private void OnSupportRequested() =>
33-
analytics.Track(AnalyticsEvents.UI.OPEN_SUPPORT);
33+
analytics.Track(AnalyticsEvents.Ui.OPEN_SUPPORT);
3434

3535
private void OnPlacesOpened() =>
3636
analytics.Track(AnalyticsEvents.Places.PLACES_SECTION_OPENED, new JObject { { "source", "sidebar" } });

Explorer/Assets/DCL/RealmNavigation/Container/RealmNavigationContainer.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ public class RealmNavigationContainer
2929
/// </summary>
3030
public IRealmNavigator RealmNavigator { get; private init; } = null!;
3131

32-
public IWorldAccessGate WorldAccessGate { get; private init; } = null!;
33-
3432
public IWorldPermissionsService WorldPermissionsService { get; private init; } = null!;
3533

3634
public IWorldInfoHub WorldInfoHub { get; private init; } = null!;
@@ -51,7 +49,7 @@ public static RealmNavigationContainer Create(
5149
ILandscape landscape,
5250
ExposedGlobalDataContainer exposedGlobalDataContainer,
5351
ILoadingScreen loadingScreen,
54-
IPlacesAPIService placesAPIService,
52+
IPlacesAPIService placesApiService,
5553
IWeb3IdentityCache identityCache,
5654
ICommunityMembershipChecker communityMembershipChecker,
5755
IMVCManager mvcManager)
@@ -75,7 +73,7 @@ public static RealmNavigationContainer Create(
7573
new RemoveRemoteEntitiesTeleportOperation(remoteEntities, globalWorld),
7674
new StopRoomAsyncTeleportOperation(roomHub, LIVEKIT_TIMEOUT),
7775
new RemoveCameraSamplingDataTeleportOperation(globalWorld, exposedGlobalDataContainer.ExposedCameraData.CameraEntityProxy),
78-
new ClearWorldsCacheTeleportOperation(placesAPIService),
76+
new ClearWorldsCacheTeleportOperation(placesApiService),
7977
new ChangeRealmTeleportOperation(realmContainer.RealmController),
8078
new AnalyticsFlushTeleportOperation(analytics),
8179
new LoadLandscapeTeleportOperation(landscape),
@@ -115,8 +113,8 @@ public static RealmNavigationContainer Create(
115113
analytics,
116114
realmChangeOperations,
117115
teleportInSameRealmOperation,
118-
worldAccessGate),
119-
WorldAccessGate = worldAccessGate,
116+
worldAccessGate,
117+
staticContainer.ScenesCache),
120118
WorldPermissionsService = worldPermissionsService,
121119
WorldInfoHub = worldInfoHub,
122120
widgetBuilder = realmContainer.DebugView.DebugWidgetBuilder

Explorer/Assets/DCL/RealmNavigation/RealmNavigator.cs

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@
1414
using DCL.Utility.Types;
1515
using ECS;
1616
using ECS.Prioritization.Components;
17+
using ECS.SceneLifeCycle;
1718
using ECS.SceneLifeCycle.Realm;
1819
using Newtonsoft.Json.Linq;
20+
using SceneRunner.Scene;
1921
using System;
2022
using System.Threading;
2123
using UnityEngine;
@@ -47,6 +49,7 @@ public class RealmNavigator : IRealmNavigator
4749
private readonly IAnalyticsController analyticsController;
4850
private readonly ILandscape landscape;
4951
private readonly IWorldAccessGate worldAccessGate;
52+
private readonly IScenesCache scenesCache;
5053

5154
public RealmNavigator(
5255
ILoadingScreen loadingScreen,
@@ -60,7 +63,8 @@ public RealmNavigator(
6063
IAnalyticsController analyticsController,
6164
SequentialLoadingOperation<TeleportParams> realmChangeOperations,
6265
SequentialLoadingOperation<TeleportParams> teleportInSameRealmOperation,
63-
IWorldAccessGate worldAccessGate)
66+
IWorldAccessGate worldAccessGate,
67+
IScenesCache scenesCache)
6468
{
6569
this.loadingScreen = loadingScreen;
6670
this.realmController = realmController;
@@ -74,6 +78,7 @@ public RealmNavigator(
7478
this.teleportInSameRealmOperation = teleportInSameRealmOperation;
7579
this.landscape = landscape;
7680
this.worldAccessGate = worldAccessGate;
81+
this.scenesCache = scenesCache;
7782
}
7883

7984
public bool IsAlreadyOnRealm(URLDomain realm)
@@ -195,9 +200,14 @@ private async UniTask<EnumResult<TaskError>> ExecuteTeleportOperationsAsync(
195200
SequentialLoadingOperation<TeleportParams> ops,
196201
string logOpName,
197202
int attemptsCount,
203+
bool trackDuration,
198204
CancellationToken ct
199205
)
200206
{
207+
// Snapshot the source before ops run: realm-change ops clear the scenes cache
208+
string source = SceneHashOrParcel(scenesCache.CurrentScene.Value, scenesCache.CurrentParcel.Value);
209+
float startTime = UnityEngine.Time.realtimeSinceStartup;
210+
201211
ReportHub.LogProductionInfo($"Trying to teleport to {teleportParams.CurrentDestinationParcel}. Attempt #{attemptsCount}");
202212
EnumResult<TaskError> lastOpResult = await ops.ExecuteAsync(logOpName, attemptsCount, teleportParams, ct);
203213

@@ -220,11 +230,31 @@ CancellationToken ct
220230
);
221231
}
222232
else
233+
{
234+
if (trackDuration)
235+
{
236+
float loadingTime = UnityEngine.Time.realtimeSinceStartup - startTime;
237+
238+
// The destination scene is already cached: teleport ops wait for scene readiness before completing
239+
scenesCache.TryGetByParcel(teleportParams.CurrentDestinationParcel, out ISceneFacade destinationScene);
240+
241+
analyticsController.Track(AnalyticsEvents.General.TELEPORT_OPERATION_DURATION, new JObject
242+
{
243+
["source"] = source,
244+
["destination"] = SceneHashOrParcel(destinationScene, teleportParams.CurrentDestinationParcel),
245+
["loading_time"] = loadingTime,
246+
});
247+
}
248+
223249
NavigationExecuted?.Invoke(teleportParams.CurrentDestinationParcel);
250+
}
224251

225252
return lastOpResult;
226253
}
227254

255+
private static string SceneHashOrParcel(ISceneFacade? scene, Vector2Int parcel) =>
256+
scene is { IsEmpty: false } ? scene.Info.Name : parcel.ToString();
257+
228258
private Func<AsyncLoadProcessReport, CancellationToken, UniTask<EnumResult<TaskError>>> DoChangeRealmAsync(URLDomain realm, URLDomain? fallbackRealm, Vector2Int parcelToTeleport, bool allowsWorldPositionOverride, bool landOnParcel = false, string? spawnPointName = null)
229259
{
230260
return async (parentLoadReport, ct) =>
@@ -237,7 +267,7 @@ private Func<AsyncLoadProcessReport, CancellationToken, UniTask<EnumResult<TaskE
237267

238268
var teleportParams = new TeleportParams(realm, parcelToTeleport, parentLoadReport, loadingStatus, allowsWorldPositionOverride, landOnParcel, spawnPointName);
239269

240-
EnumResult<TaskError> opResult = await ExecuteTeleportOperationsAsync(teleportParams, realmChangeOperations, LOG_NAME, MAX_REALM_CHANGE_RETRIES, ct);
270+
EnumResult<TaskError> opResult = await ExecuteTeleportOperationsAsync(teleportParams, realmChangeOperations, LOG_NAME, MAX_REALM_CHANGE_RETRIES, trackDuration: true, ct);
241271

242272
if (opResult.Success)
243273
return opResult;
@@ -253,7 +283,8 @@ private Func<AsyncLoadProcessReport, CancellationToken, UniTask<EnumResult<TaskE
253283

254284
teleportParams.ChangeDestination(fallbackRealm.Value, currentParcel);
255285

256-
opResult = await ExecuteTeleportOperationsAsync(teleportParams, realmChangeOperations, FALLBACK_LOG_NAME, 1, ct);
286+
// The recovery trip back is not a user-intended teleport: keep it out of the duration metric
287+
opResult = await ExecuteTeleportOperationsAsync(teleportParams, realmChangeOperations, FALLBACK_LOG_NAME, 1, trackDuration: false, ct);
257288

258289
if (!opResult.Success)
259290
parentLoadReport.SetProgress(1);
@@ -331,7 +362,7 @@ private Func<AsyncLoadProcessReport, CancellationToken, UniTask<EnumResult<TaskE
331362
spawnPointName: spawnPointName
332363
);
333364

334-
EnumResult<TaskError> result = await ExecuteTeleportOperationsAsync(teleportParams, teleportInSameRealmOperation, LOG_NAME, 1, ct);
365+
EnumResult<TaskError> result = await ExecuteTeleportOperationsAsync(teleportParams, teleportInSameRealmOperation, LOG_NAME, 1, trackDuration: true, ct);
335366
return result;
336367
};
337368
}

0 commit comments

Comments
 (0)