< Summary

Class:Catalyst
Assembly:Catalyst
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/ServiceProviders/Catalyst/Catalyst.cs
Covered lines:10
Uncovered lines:90
Coverable lines:100
Total lines:210
Line coverage:10% (10 of 100)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
Catalyst()0%2.042077.78%
Dispose()0%110100%
GetContent()0%12300%
GetDeployedScenes(...)0%2100%
GetDeployedScenes(...)0%20400%
GetEntities(...)0%1101000%
Get(...)0%2100%
PlayerRealmOnOnChange(...)0%2100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/ServiceProviders/Catalyst/Catalyst.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using Cysharp.Threading.Tasks;
 5using DCL;
 6using DCL.Helpers;
 7using UnityEngine;
 8using Variables.RealmsInfo;
 9
 10public class Catalyst : ICatalyst
 11{
 12    private const float DEFAULT_CACHE_TIME = 5 * 60;
 13    private const int MAX_POINTERS_PER_REQUEST = 90;
 14
 015    public string contentUrl => realmContentServerUrl;
 016    public string lambdasUrl => $"{realmDomain}/lambdas";
 17
 10818    private string realmDomain = "https://peer.decentraland.org";
 10819    private string realmContentServerUrl = "https://peer.decentraland.org/content";
 20
 10821    private readonly IDataCache<CatalystSceneEntityPayload[]> deployedScenesCache = new DataCache<CatalystSceneEntityPay
 22
 10823    public Catalyst()
 24    {
 10825        if (DataStore.i.realm.playerRealm.Get() != null)
 26        {
 027            realmDomain = DataStore.i.realm.playerRealm.Get().domain;
 028            realmContentServerUrl = DataStore.i.realm.playerRealm.Get().contentServerUrl;
 29        }
 30
 10831        DataStore.i.realm.playerRealm.OnChange += PlayerRealmOnOnChange;
 10832    }
 33
 34    public void Dispose()
 35    {
 10836        DataStore.i.realm.playerRealm.OnChange -= PlayerRealmOnOnChange;
 10837        deployedScenesCache.Dispose();
 10838    }
 39
 40    public async UniTask<string> GetContent(string hash)
 41    {
 042        string callResult = "";
 043        string url = $"{realmContentServerUrl}/contents/" + hash;
 44
 045        var callPromise = Get(url);
 046        callPromise.Then( result =>
 47        {
 048            callResult = result;
 049        });
 50
 051        callPromise.Catch( error =>
 52        {
 053            callResult = error;
 054        });
 055        await callPromise;
 056        return callResult;
 057    }
 58
 059    public Promise<CatalystSceneEntityPayload[]> GetDeployedScenes(string[] parcels) { return GetDeployedScenes(parcels,
 60
 61    public Promise<CatalystSceneEntityPayload[]> GetDeployedScenes(string[] parcels, float cacheMaxAgeSeconds)
 62    {
 063        var promise = new Promise<CatalystSceneEntityPayload[]>();
 64
 065        string cacheKey = string.Join(";", parcels);
 66
 067        if (cacheMaxAgeSeconds >= 0)
 68        {
 069            if (deployedScenesCache.TryGet(cacheKey, out CatalystSceneEntityPayload[] cacheValue, out float lastUpdate))
 70            {
 071                if (Time.unscaledTime - lastUpdate <= cacheMaxAgeSeconds)
 72                {
 073                    promise.Resolve(cacheValue);
 074                    return promise;
 75                }
 76            }
 77        }
 78
 079        GetEntities(CatalystEntitiesType.SCENE, parcels)
 80            .Then(json =>
 81            {
 082                CatalystSceneEntityPayload[] scenes = null;
 083                bool hasException = false;
 84                try
 85                {
 086                    CatalystSceneEntityPayload[] parsedValue = Utils.ParseJsonArray<CatalystSceneEntityPayload[]>(json);
 87
 88                    // remove duplicated
 089                    List<CatalystSceneEntityPayload> noDuplicates = new List<CatalystSceneEntityPayload>();
 090                    for (int i = 0; i < parsedValue.Length; i++)
 91                    {
 092                        var sceneToCheck = parsedValue[i];
 093                        if (noDuplicates.Any(scene => scene.id == sceneToCheck.id))
 94                            continue;
 95
 096                        noDuplicates.Add(sceneToCheck);
 97                    }
 98
 099                    scenes = noDuplicates.ToArray();
 0100                }
 0101                catch (Exception e)
 102                {
 0103                    promise.Reject(e.Message);
 0104                    hasException = true;
 0105                }
 106                finally
 107                {
 0108                    if (!hasException)
 109                    {
 0110                        deployedScenesCache.Add(cacheKey, scenes, DEFAULT_CACHE_TIME);
 0111                        promise.Resolve(scenes);
 112                    }
 0113                }
 0114            })
 0115            .Catch(error => promise.Reject(error));
 116
 0117        return promise;
 118    }
 119
 120    public Promise<string> GetEntities(string entityType, string[] pointers)
 121    {
 0122        Promise<string> promise = new Promise<string>();
 123
 124        string[][] pointersGroupsToFetch;
 125
 0126        if (pointers.Length <= MAX_POINTERS_PER_REQUEST)
 127        {
 0128            pointersGroupsToFetch = new [] { pointers };
 0129        }
 130        else
 131        {
 132            // split pointers array in length of MAX_POINTERS_PER_REQUEST
 0133            int i = 0;
 0134            var query = from s in pointers
 0135                let num = i++
 0136                group s by num / MAX_POINTERS_PER_REQUEST
 137                into g
 0138                select g.ToArray();
 0139            pointersGroupsToFetch = query.ToArray();
 140        }
 141
 0142        if (pointersGroupsToFetch.Length == 0)
 143        {
 0144            promise.Reject("error: no pointers to fetch");
 0145            return promise;
 146        }
 147
 0148        Promise<string>[] splittedPromises = new Promise<string>[pointersGroupsToFetch.Length];
 149
 0150        for (int i = 0; i < pointersGroupsToFetch.Length; i++)
 151        {
 0152            string urlParams = "";
 0153            urlParams = pointersGroupsToFetch[i].Aggregate(urlParams, (current, pointer) => current + $"&pointer={pointe
 0154            string url = $"{realmContentServerUrl}/entities/{entityType}?{urlParams}";
 155
 0156            splittedPromises[i] = Get(url);
 0157            splittedPromises[i]
 158                .Then(value =>
 159                {
 160                    // check if all other promises have been resolved
 0161                    for (int j = 0; j < splittedPromises.Length; j++)
 162                    {
 0163                        if (splittedPromises[j] == null || splittedPromises[j].keepWaiting || !string.IsNullOrEmpty(spli
 164                        {
 0165                            return;
 166                        }
 167                    }
 168
 169                    // make sure not to continue if promise was already resolved
 0170                    if (!promise.keepWaiting)
 0171                        return;
 172
 173                    // build json with all promises result
 0174                    string json = splittedPromises[0].value.Substring(1, splittedPromises[0].value.Length - 2);
 0175                    for (int j = 1; j < splittedPromises.Length; j++)
 176                    {
 0177                        string jsonContent = splittedPromises[j].value.Substring(1, splittedPromises[j].value.Length - 2
 0178                        if (!string.IsNullOrEmpty(jsonContent))
 0179                            json += $",{jsonContent}";
 180                    }
 181
 0182                    promise.Resolve($"[{json}]");
 0183                });
 0184            splittedPromises[i].Catch(error => promise.Reject(error));
 185        }
 186
 0187        return promise;
 188    }
 189
 190    public Promise<string> Get(string url)
 191    {
 0192        Promise<string> promise = new Promise<string>();
 193
 0194        DCL.Environment.i.platform.webRequest.Get(url, null, request =>
 195        {
 0196            promise.Resolve(request.webRequest.downloadHandler.text);
 0197        }, request =>
 198        {
 0199            promise.Reject($"{request.webRequest.error} {request.webRequest.downloadHandler.text} at url {url}");
 0200        });
 201
 0202        return promise;
 203    }
 204
 205    private void PlayerRealmOnOnChange(CurrentRealmModel current, CurrentRealmModel previous)
 206    {
 0207        realmDomain = current.domain;
 0208        realmContentServerUrl = current.contentServerUrl;
 0209    }
 210}