Skip to content

Commit f08c5c1

Browse files
authored
Assert possible recursion (#6341)
- Clearify the flow of exceptions
1 parent 2d0132d commit f08c5c1

4 files changed

Lines changed: 28 additions & 25 deletions

File tree

Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/Cache/IntentionsComparer.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ public override int GetHashCode() =>
4040

4141
public static bool operator !=(SourcedIntentionId left, SourcedIntentionId right) =>
4242
!left.Equals(right);
43-
}
43+
44+
public override string ToString() =>
45+
$"Intention: {intention}, Source: {source}";
46+
}
4447
}
45-
}
48+
}

Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/Common/Systems/AssetsLoadingUtility.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public delegate UniTask<StreamableLoadingResult<TAsset>> InternalFlowDelegate<TA
2121
/// <summary>
2222
/// Repeat the internal flow until attempts do not exceed or an irrecoverable error occurs
2323
/// </summary>
24+
/// <exception cref="OperationCanceledException">(And if it's an inner exception) is propagated to the upper flow, all other exceptions are translated into StreamableLoadingResult</exception>
2425
/// <returns>
2526
/// <para>Null - if PermittedSources have value</para>
2627
/// </returns>

Explorer/Assets/DCL/Infrastructure/ECS/StreamableLoading/Common/Systems/LoadSystemBase.cs

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
using System;
1414
using System.Runtime.CompilerServices;
1515
using System.Threading;
16+
using UnityEngine;
1617
using Utility;
1718

1819
namespace ECS.StreamableLoading.Common.Systems
@@ -146,13 +147,20 @@ CancellationToken disposalCt
146147
// if the cached request is cancelled it does not mean failure for the new intent
147148
(requestIsNotFulfilled, ongoingRequestResult) = await cachedSource.Task.SuppressCancellationThrow();
148149

149-
//Temporarly disabled as we don't have partial loading integrated
150+
//Temporarily disabled as we don't have partial loading integrated
150151
//SynchronizePartialData(state, ongoingRequestResult);
151152

152153
result = ongoingRequestResult.Result;
153154

154155
if (requestIsNotFulfilled)
155156
{
157+
// Assert the recursion possibility
158+
// At this point the request should never be ongoing
159+
if (cache.OngoingRequests.SyncRemove(intentionId))
160+
161+
// Break the flow instead of trying to continue - we have to find and fix the origin of the issue
162+
throw new StreamableLoadingException(LogType.Exception, $"Execution of {intentionId} caused recursion");
163+
156164
await FlowAsync(entity, source, intention, state, partition, intentionId, disposalCt);
157165
return;
158166
}
@@ -286,7 +294,6 @@ protected abstract UniTask<StreamableLoadingResult<TAsset>> FlowInternalAsync(TI
286294
var source = new UniTaskCompletionSource<OngoingRequestResult<TAsset>>(); //AutoResetUniTaskCompletionSource<StreamableLoadingResult<TAsset>?>.Create();
287295

288296
cache.OngoingRequests.SyncTryAdd(intentionId, source);
289-
var ongoingRequestRemoved = false;
290297

291298
StreamableLoadingResult<TAsset>? result = null;
292299

@@ -303,15 +310,14 @@ protected abstract UniTask<StreamableLoadingResult<TAsset>> FlowInternalAsync(TI
303310
if (result is { Succeeded: true })
304311
genericCache
305312
.PutAsync(intention, result.Value.Asset!, intention.IsQualifiedForDiskCache(), ct)
306-
.Forget(
307-
static e =>
308-
ReportHub.LogError(ReportCategory.STREAMABLE_LOADING, $"Error putting cache content: {e.Message}")
313+
.Forget(static e =>
314+
ReportHub.LogError(ReportCategory.STREAMABLE_LOADING, $"Error putting cache content: {e.Message}")
309315
);
310316

311317
// Set result for the reusable source
312318
// Remove from the ongoing requests immediately because finally will be called later than
313319
// continuation of cachedSource.Task.SuppressCancellationThrow();
314-
TryRemoveOngoingRequest();
320+
RemoveOngoingRequest();
315321

316322
source.TrySetResult(new OngoingRequestResult<TAsset>(state.PartialDownloadingData, result));
317323

@@ -320,33 +326,26 @@ protected abstract UniTask<StreamableLoadingResult<TAsset>> FlowInternalAsync(TI
320326
// (e.g. if in StreamingAssets the requested asset is not present, arguments to download from WEB source will be prepared separately)
321327
return result;
322328
}
323-
catch (OperationCanceledException operationCanceledException)
329+
catch (Exception e) when (e is OperationCanceledException || e.InnerException is OperationCanceledException)
324330
{
325331
if (result is { Succeeded: true })
326332
DisposeAbandonedResult(result.Value.Asset!);
327333

328334
// Remove from the ongoing requests immediately because finally will be called later than
329335
// continuation of cachedSource.Task.SuppressCancellationThrow();
330-
TryRemoveOngoingRequest();
336+
RemoveOngoingRequest();
331337

332338
// Cancellation does not produce asset result
333-
source.TrySetCanceled(operationCanceledException.CancellationToken);
339+
source.TrySetCanceled(ct);
334340
throw;
335341
}
336-
finally
337-
{
338-
// We need to remove the request the same frame to prevent de-sync with new requests
339-
TryRemoveOngoingRequest();
340-
}
341342

342-
void TryRemoveOngoingRequest()
343+
// Other exceptions are impossible according to the flow
344+
345+
void RemoveOngoingRequest()
343346
{
344-
if (!ongoingRequestRemoved)
345-
{
346-
// ReportHub.Log(GetReportCategory(), $"OngoingRequests.SyncRemove {intention.CommonArguments.URL}");
347-
cache.OngoingRequests.SyncRemove(intentionId);
348-
ongoingRequestRemoved = true;
349-
}
347+
// ReportHub.Log(GetReportCategory(), $"OngoingRequests.SyncRemove {intention.CommonArguments.URL}");
348+
cache.OngoingRequests.SyncRemove(intentionId);
350349
}
351350
}
352351

Explorer/Assets/DCL/Infrastructure/Utility/Extensions/CollectionsExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ namespace Utility
77
public static class CollectionsExtensions
88
{
99
[MethodImpl(MethodImplOptions.AggressiveInlining)]
10-
public static void SyncRemove<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
10+
public static bool SyncRemove<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
1111
{
12-
lock (dictionary) { dictionary.Remove(key); }
12+
lock (dictionary) { return dictionary.Remove(key); }
1313
}
1414

1515
public static void SyncAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TValue value)

0 commit comments

Comments
 (0)