< 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:78
Coverable lines:88
Total lines:190
Line coverage:11.3% (10 of 88)
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%
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 DCL;
 5using DCL.Helpers;
 6using UnityEngine;
 7using Variables.RealmsInfo;
 8
 9public class Catalyst : ICatalyst
 10{
 11    private const float DEFAULT_CACHE_TIME = 5 * 60;
 12    private const int MAX_POINTERS_PER_REQUEST = 90;
 13
 014    public string contentUrl => realmContentServerUrl;
 015    public string lambdasUrl => $"{realmDomain}/lambdas";
 16
 7217    private string realmDomain = "https://peer-lb.decentraland.org";
 7218    private string realmContentServerUrl = "https://peer-lb.decentraland.org/content";
 19
 7220    private readonly IDataCache<CatalystSceneEntityPayload[]> deployedScenesCache = new DataCache<CatalystSceneEntityPay
 21
 7222    public Catalyst()
 23    {
 7224        if (DataStore.i.realm.playerRealm.Get() != null)
 25        {
 026            realmDomain = DataStore.i.realm.playerRealm.Get().domain;
 027            realmContentServerUrl = DataStore.i.realm.playerRealm.Get().contentServerUrl;
 28        }
 29
 7230        DataStore.i.realm.playerRealm.OnChange += PlayerRealmOnOnChange;
 7231    }
 32
 33    public void Dispose()
 34    {
 7235        DataStore.i.realm.playerRealm.OnChange -= PlayerRealmOnOnChange;
 7236        deployedScenesCache.Dispose();
 7237    }
 38
 039    public Promise<CatalystSceneEntityPayload[]> GetDeployedScenes(string[] parcels) { return GetDeployedScenes(parcels,
 40
 41    public Promise<CatalystSceneEntityPayload[]> GetDeployedScenes(string[] parcels, float cacheMaxAgeSeconds)
 42    {
 043        var promise = new Promise<CatalystSceneEntityPayload[]>();
 44
 045        string cacheKey = string.Join(";", parcels);
 46
 047        if (cacheMaxAgeSeconds >= 0)
 48        {
 049            if (deployedScenesCache.TryGet(cacheKey, out CatalystSceneEntityPayload[] cacheValue, out float lastUpdate))
 50            {
 051                if (Time.unscaledTime - lastUpdate <= cacheMaxAgeSeconds)
 52                {
 053                    promise.Resolve(cacheValue);
 054                    return promise;
 55                }
 56            }
 57        }
 58
 059        GetEntities(CatalystEntitiesType.SCENE, parcels)
 60            .Then(json =>
 61            {
 062                CatalystSceneEntityPayload[] scenes = null;
 063                bool hasException = false;
 64                try
 65                {
 066                    CatalystSceneEntityPayload[] parsedValue = Utils.ParseJsonArray<CatalystSceneEntityPayload[]>(json);
 67
 68                    // remove duplicated
 069                    List<CatalystSceneEntityPayload> noDuplicates = new List<CatalystSceneEntityPayload>();
 070                    for (int i = 0; i < parsedValue.Length; i++)
 71                    {
 072                        var sceneToCheck = parsedValue[i];
 073                        if (noDuplicates.Any(scene => scene.id == sceneToCheck.id))
 74                            continue;
 75
 076                        noDuplicates.Add(sceneToCheck);
 77                    }
 78
 079                    scenes = noDuplicates.ToArray();
 080                }
 081                catch (Exception e)
 82                {
 083                    promise.Reject(e.Message);
 084                    hasException = true;
 085                }
 86                finally
 87                {
 088                    if (!hasException)
 89                    {
 090                        deployedScenesCache.Add(cacheKey, scenes, DEFAULT_CACHE_TIME);
 091                        promise.Resolve(scenes);
 92                    }
 093                }
 094            })
 095            .Catch(error => promise.Reject(error));
 96
 097        return promise;
 98    }
 99
 100    public Promise<string> GetEntities(string entityType, string[] pointers)
 101    {
 0102        Promise<string> promise = new Promise<string>();
 103
 104        string[][] pointersGroupsToFetch;
 105
 0106        if (pointers.Length <= MAX_POINTERS_PER_REQUEST)
 107        {
 0108            pointersGroupsToFetch = new [] { pointers };
 0109        }
 110        else
 111        {
 112            // split pointers array in length of MAX_POINTERS_PER_REQUEST
 0113            int i = 0;
 0114            var query = from s in pointers
 0115                let num = i++
 0116                group s by num / MAX_POINTERS_PER_REQUEST
 117                into g
 0118                select g.ToArray();
 0119            pointersGroupsToFetch = query.ToArray();
 120        }
 121
 0122        if (pointersGroupsToFetch.Length == 0)
 123        {
 0124            promise.Reject("error: no pointers to fetch");
 0125            return promise;
 126        }
 127
 0128        Promise<string>[] splittedPromises = new Promise<string>[pointersGroupsToFetch.Length];
 129
 0130        for (int i = 0; i < pointersGroupsToFetch.Length; i++)
 131        {
 0132            string urlParams = "";
 0133            urlParams = pointersGroupsToFetch[i].Aggregate(urlParams, (current, pointer) => current + $"&pointer={pointe
 0134            string url = $"{realmContentServerUrl}/entities/{entityType}?{urlParams}";
 135
 0136            splittedPromises[i] = Get(url);
 0137            splittedPromises[i]
 138                .Then(value =>
 139                {
 140                    // check if all other promises have been resolved
 0141                    for (int j = 0; j < splittedPromises.Length; j++)
 142                    {
 0143                        if (splittedPromises[j] == null || splittedPromises[j].keepWaiting || !string.IsNullOrEmpty(spli
 144                        {
 0145                            return;
 146                        }
 147                    }
 148
 149                    // make sure not to continue if promise was already resolved
 0150                    if (!promise.keepWaiting)
 0151                        return;
 152
 153                    // build json with all promises result
 0154                    string json = splittedPromises[0].value.Substring(1, splittedPromises[0].value.Length - 2);
 0155                    for (int j = 1; j < splittedPromises.Length; j++)
 156                    {
 0157                        string jsonContent = splittedPromises[j].value.Substring(1, splittedPromises[j].value.Length - 2
 0158                        if (!string.IsNullOrEmpty(jsonContent))
 0159                            json += $",{jsonContent}";
 160                    }
 161
 0162                    promise.Resolve($"[{json}]");
 0163                });
 0164            splittedPromises[i].Catch(error => promise.Reject(error));
 165        }
 166
 0167        return promise;
 168    }
 169
 170    public Promise<string> Get(string url)
 171    {
 0172        Promise<string> promise = new Promise<string>();
 173
 0174        DCL.Environment.i.platform.webRequest.Get(url, null, request =>
 175        {
 0176            promise.Resolve(request.webRequest.downloadHandler.text);
 0177        }, request =>
 178        {
 0179            promise.Reject($"{request.webRequest.error} {request.webRequest.downloadHandler.text} at url {url}");
 0180        });
 181
 0182        return promise;
 183    }
 184
 185    private void PlayerRealmOnOnChange(CurrentRealmModel current, CurrentRealmModel previous)
 186    {
 0187        realmDomain = current.domain;
 0188        realmContentServerUrl = current.contentServerUrl;
 0189    }
 190}