< Summary

Class:Catalyst
Assembly:Catalyst
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/ServiceProviders/Catalyst/Catalyst.cs
Covered lines:23
Uncovered lines:84
Coverable lines:107
Total lines:235
Line coverage:21.4% (23 of 107)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
Catalyst()0%5.335076.47%
Dispose()0%110100%
GetContent()0%12300%
GetDeployedScenes(...)0%2100%
GetDeployedScenes(...)0%20400%
GetEntities(...)0%1101000%
Get(...)0%2100%
PlayerRealmOnChange(...)0%2100%
PlayerRealmAboutLambdasOnChange(...)0%2100%
PlayerRealmAboutContentOnChange(...)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 Decentraland.Bff;
 8using UnityEngine;
 9using Variables.RealmsInfo;
 10
 11public class Catalyst : ICatalyst
 12{
 13    private const float DEFAULT_CACHE_TIME = 5 * 60;
 14    private const int MAX_POINTERS_PER_REQUEST = 90;
 15
 016    public string contentUrl => realmContentServerUrl;
 117    public string lambdasUrl { get; private set; }
 18
 12219    private string realmDomain = "https://peer.decentraland.org";
 12220    private string realmContentServerUrl = "https://peer.decentraland.org/content";
 21
 12222    private readonly IDataCache<CatalystSceneEntityPayload[]> deployedScenesCache = new DataCache<CatalystSceneEntityPay
 23
 36824    private CurrentRealmVariable playerRealm => DataStore.i.realm.playerRealm;
 24425    private BaseVariable<AboutResponse.Types.LambdasInfo> aboutLambdas => DataStore.i.realm.playerRealmAboutLambdas;
 24426    private BaseVariable<AboutResponse.Types.ContentInfo> aboutContent => DataStore.i.realm.playerRealmAboutContent;
 12127    private BaseVariable<AboutResponse.Types.AboutConfiguration> aboutConfiguration => DataStore.i.realm.playerRealmAbou
 28
 29
 12230    public Catalyst()
 31    {
 12232        if (playerRealm.Get() != null)
 33        {
 134            realmDomain = playerRealm.Get().domain;
 135            lambdasUrl = $"{realmDomain}/lambdas";
 136            realmContentServerUrl = playerRealm.Get().contentServerUrl;
 37        }
 12138        else if (aboutConfiguration.Get() != null)
 39        {
 40            //TODO: This checks are going to dissapear when we inject the urls in kernel. Currently they are null,
 41            //and we dont want to override the ones that have been set up in playerRealm
 042            if (!string.IsNullOrEmpty(aboutLambdas.Get().PublicUrl))
 043                lambdasUrl = aboutLambdas.Get().PublicUrl;
 44
 045            if (!string.IsNullOrEmpty(aboutContent.Get().PublicUrl))
 046                realmContentServerUrl = aboutContent.Get().PublicUrl;
 47        }
 48
 12249        playerRealm.OnChange += PlayerRealmOnChange;
 12250        aboutContent.OnChange += PlayerRealmAboutContentOnChange;
 12251        aboutLambdas.OnChange += PlayerRealmAboutLambdasOnChange;
 12252    }
 53
 54    public void Dispose()
 55    {
 12256        playerRealm.OnChange -= PlayerRealmOnChange;
 12257        aboutContent.OnChange -= PlayerRealmAboutContentOnChange;
 12258        aboutLambdas.OnChange -= PlayerRealmAboutLambdasOnChange;
 12259        deployedScenesCache.Dispose();
 12260    }
 61
 62    public async UniTask<string> GetContent(string hash)
 63    {
 064        string callResult = "";
 065        string url = $"{realmContentServerUrl}/contents/" + hash;
 66
 067        var callPromise = Get(url);
 068        callPromise.Then(result => { callResult = result; });
 69
 070        callPromise.Catch(error => { callResult = error; });
 071        await callPromise;
 072        return callResult;
 073    }
 74
 75    public Promise<CatalystSceneEntityPayload[]> GetDeployedScenes(string[] parcels)
 76    {
 077        return GetDeployedScenes(parcels, DEFAULT_CACHE_TIME);
 78    }
 79
 80    public Promise<CatalystSceneEntityPayload[]> GetDeployedScenes(string[] parcels, float cacheMaxAgeSeconds)
 81    {
 082        var promise = new Promise<CatalystSceneEntityPayload[]>();
 83
 084        string cacheKey = string.Join(";", parcels);
 85
 086        if (cacheMaxAgeSeconds >= 0)
 87        {
 088            if (deployedScenesCache.TryGet(cacheKey, out CatalystSceneEntityPayload[] cacheValue, out float lastUpdate))
 89            {
 090                if (Time.unscaledTime - lastUpdate <= cacheMaxAgeSeconds)
 91                {
 092                    promise.Resolve(cacheValue);
 093                    return promise;
 94                }
 95            }
 96        }
 97
 098        GetEntities(CatalystEntitiesType.SCENE, parcels)
 99           .Then(json =>
 100            {
 0101                CatalystSceneEntityPayload[] scenes = null;
 0102                bool hasException = false;
 103
 104                try
 105                {
 0106                    CatalystSceneEntityPayload[] parsedValue = Utils.ParseJsonArray<CatalystSceneEntityPayload[]>(json);
 107
 108                    // remove duplicated
 0109                    List<CatalystSceneEntityPayload> noDuplicates = new List<CatalystSceneEntityPayload>();
 110
 0111                    for (int i = 0; i < parsedValue.Length; i++)
 112                    {
 0113                        var sceneToCheck = parsedValue[i];
 114
 0115                        if (noDuplicates.Any(scene => scene.id == sceneToCheck.id))
 116                            continue;
 117
 0118                        noDuplicates.Add(sceneToCheck);
 119                    }
 120
 0121                    scenes = noDuplicates.ToArray();
 0122                }
 0123                catch (Exception e)
 124                {
 0125                    promise.Reject(e.Message);
 0126                    hasException = true;
 0127                }
 128                finally
 129                {
 0130                    if (!hasException)
 131                    {
 0132                        deployedScenesCache.Add(cacheKey, scenes, DEFAULT_CACHE_TIME);
 0133                        promise.Resolve(scenes);
 134                    }
 0135                }
 0136            })
 0137           .Catch(error => promise.Reject(error));
 138
 0139        return promise;
 140    }
 141
 142    public Promise<string> GetEntities(string entityType, string[] pointers)
 143    {
 0144        Promise<string> promise = new Promise<string>();
 145
 146        string[][] pointersGroupsToFetch;
 147
 0148        if (pointers.Length <= MAX_POINTERS_PER_REQUEST) { pointersGroupsToFetch = new[] { pointers }; }
 149        else
 150        {
 151            // split pointers array in length of MAX_POINTERS_PER_REQUEST
 0152            int i = 0;
 153
 0154            var query = from s in pointers
 0155                let num = i++
 0156                group s by num / MAX_POINTERS_PER_REQUEST
 157                into g
 0158                select g.ToArray();
 159
 0160            pointersGroupsToFetch = query.ToArray();
 161        }
 162
 0163        if (pointersGroupsToFetch.Length == 0)
 164        {
 0165            promise.Reject("error: no pointers to fetch");
 0166            return promise;
 167        }
 168
 0169        Promise<string>[] splittedPromises = new Promise<string>[pointersGroupsToFetch.Length];
 170
 0171        for (int i = 0; i < pointersGroupsToFetch.Length; i++)
 172        {
 0173            string urlParams = "";
 0174            urlParams = pointersGroupsToFetch[i].Aggregate(urlParams, (current, pointer) => current + $"&pointer={pointe
 0175            string url = $"{realmContentServerUrl}/entities/{entityType}?{urlParams}";
 176
 0177            splittedPromises[i] = Get(url);
 178
 0179            splittedPromises[i]
 180               .Then(value =>
 181                {
 182                    // check if all other promises have been resolved
 0183                    for (int j = 0; j < splittedPromises.Length; j++)
 184                    {
 0185                        if (splittedPromises[j] == null || splittedPromises[j].keepWaiting || !string.IsNullOrEmpty(spli
 186                    }
 187
 188                    // make sure not to continue if promise was already resolved
 0189                    if (!promise.keepWaiting)
 0190                        return;
 191
 192                    // build json with all promises result
 0193                    string json = splittedPromises[0].value.Substring(1, splittedPromises[0].value.Length - 2);
 194
 0195                    for (int j = 1; j < splittedPromises.Length; j++)
 196                    {
 0197                        string jsonContent = splittedPromises[j].value.Substring(1, splittedPromises[j].value.Length - 2
 198
 0199                        if (!string.IsNullOrEmpty(jsonContent))
 0200                            json += $",{jsonContent}";
 201                    }
 202
 0203                    promise.Resolve($"[{json}]");
 0204                });
 205
 0206            splittedPromises[i].Catch(error => promise.Reject(error));
 207        }
 208
 0209        return promise;
 210    }
 211
 212    public Promise<string> Get(string url)
 213    {
 0214        Promise<string> promise = new Promise<string>();
 215
 0216        DCL.Environment.i.platform.webRequest.Get(url, null, request => { promise.Resolve(request.webRequest.downloadHan
 217
 0218        return promise;
 219    }
 220
 221    private void PlayerRealmOnChange(CurrentRealmModel current, CurrentRealmModel previous)
 222    {
 0223        realmDomain = current.domain;
 0224        lambdasUrl = $"{realmDomain}/lambdas";
 0225        realmContentServerUrl = current.contentServerUrl;
 0226    }
 227
 228    private void PlayerRealmAboutLambdasOnChange(AboutResponse.Types.LambdasInfo current, AboutResponse.Types.LambdasInf
 229    {
 0230        lambdasUrl = current.PublicUrl;
 0231    }
 232
 233    private void PlayerRealmAboutContentOnChange(AboutResponse.Types.ContentInfo current, AboutResponse.Types.ContentInf
 0234        realmContentServerUrl = current.PublicUrl;
 235}