< Summary

Class:Catalyst
Assembly:Catalyst
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/ServiceProviders/Catalyst/Catalyst.cs
Covered lines:12
Uncovered lines:75
Coverable lines:87
Total lines:189
Line coverage:13.7% (12 of 87)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
Catalyst()0%220100%
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;
 15
 67116    private string realmDomain = "https://peer-lb.decentraland.org";
 67117    private string realmContentServerUrl = "https://peer-lb.decentraland.org/content";
 18
 67119    private readonly IDataCache<CatalystSceneEntityPayload[]> deployedScenesCache = new DataCache<CatalystSceneEntityPay
 20
 67121    public Catalyst()
 22    {
 67123        if (DataStore.i.playerRealm.Get() != null)
 24        {
 125            realmDomain = DataStore.i.playerRealm.Get().domain;
 126            realmContentServerUrl = DataStore.i.playerRealm.Get().contentServerUrl;
 27        }
 28
 67129        DataStore.i.playerRealm.OnChange += PlayerRealmOnOnChange;
 67130    }
 31
 32    public void Dispose()
 33    {
 69234        DataStore.i.playerRealm.OnChange -= PlayerRealmOnOnChange;
 69235        deployedScenesCache.Dispose();
 69236    }
 37
 038    public Promise<CatalystSceneEntityPayload[]> GetDeployedScenes(string[] parcels) { return GetDeployedScenes(parcels,
 39
 40    public Promise<CatalystSceneEntityPayload[]> GetDeployedScenes(string[] parcels, float cacheMaxAgeSeconds)
 41    {
 042        var promise = new Promise<CatalystSceneEntityPayload[]>();
 43
 044        string cacheKey = string.Join(";", parcels);
 45
 046        if (cacheMaxAgeSeconds >= 0)
 47        {
 048            if (deployedScenesCache.TryGet(cacheKey, out CatalystSceneEntityPayload[] cacheValue, out float lastUpdate))
 49            {
 050                if (Time.unscaledTime - lastUpdate <= cacheMaxAgeSeconds)
 51                {
 052                    promise.Resolve(cacheValue);
 053                    return promise;
 54                }
 55            }
 56        }
 57
 058        GetEntities(CatalystEntitiesType.SCENE, parcels)
 59            .Then(json =>
 60            {
 061                CatalystSceneEntityPayload[] scenes = null;
 062                bool hasException = false;
 63                try
 64                {
 065                    CatalystSceneEntityPayload[] parsedValue = Utils.ParseJsonArray<CatalystSceneEntityPayload[]>(json);
 66
 67                    // remove duplicated
 068                    List<CatalystSceneEntityPayload> noDuplicates = new List<CatalystSceneEntityPayload>();
 069                    for (int i = 0; i < parsedValue.Length; i++)
 70                    {
 071                        var sceneToCheck = parsedValue[i];
 072                        if (noDuplicates.Any(scene => scene.id == sceneToCheck.id))
 73                            continue;
 74
 075                        noDuplicates.Add(sceneToCheck);
 76                    }
 77
 078                    scenes = noDuplicates.ToArray();
 079                }
 080                catch (Exception e)
 81                {
 082                    promise.Reject(e.Message);
 083                    hasException = true;
 084                }
 85                finally
 86                {
 087                    if (!hasException)
 88                    {
 089                        deployedScenesCache.Add(cacheKey, scenes, DEFAULT_CACHE_TIME);
 090                        promise.Resolve(scenes);
 91                    }
 092                }
 093            })
 094            .Catch(error => promise.Reject(error));
 95
 096        return promise;
 97    }
 98
 99    public Promise<string> GetEntities(string entityType, string[] pointers)
 100    {
 0101        Promise<string> promise = new Promise<string>();
 102
 103        string[][] pointersGroupsToFetch;
 104
 0105        if (pointers.Length <= MAX_POINTERS_PER_REQUEST)
 106        {
 0107            pointersGroupsToFetch = new [] { pointers };
 0108        }
 109        else
 110        {
 111            // split pointers array in length of MAX_POINTERS_PER_REQUEST
 0112            int i = 0;
 0113            var query = from s in pointers
 0114                let num = i++
 0115                group s by num / MAX_POINTERS_PER_REQUEST
 116                into g
 0117                select g.ToArray();
 0118            pointersGroupsToFetch = query.ToArray();
 119        }
 120
 0121        if (pointersGroupsToFetch.Length == 0)
 122        {
 0123            promise.Reject("error: no pointers to fetch");
 0124            return promise;
 125        }
 126
 0127        Promise<string>[] splittedPromises = new Promise<string>[pointersGroupsToFetch.Length];
 128
 0129        for (int i = 0; i < pointersGroupsToFetch.Length; i++)
 130        {
 0131            string urlParams = "";
 0132            urlParams = pointersGroupsToFetch[i].Aggregate(urlParams, (current, pointer) => current + $"&pointer={pointe
 0133            string url = $"{realmContentServerUrl}/entities/{entityType}?{urlParams}";
 134
 0135            splittedPromises[i] = Get(url);
 0136            splittedPromises[i]
 137                .Then(value =>
 138                {
 139                    // check if all other promises have been resolved
 0140                    for (int j = 0; j < splittedPromises.Length; j++)
 141                    {
 0142                        if (splittedPromises[j] == null || splittedPromises[j].keepWaiting || !string.IsNullOrEmpty(spli
 143                        {
 0144                            return;
 145                        }
 146                    }
 147
 148                    // make sure not to continue if promise was already resolved
 0149                    if (!promise.keepWaiting)
 0150                        return;
 151
 152                    // build json with all promises result
 0153                    string json = splittedPromises[0].value.Substring(1, splittedPromises[0].value.Length - 2);
 0154                    for (int j = 1; j < splittedPromises.Length; j++)
 155                    {
 0156                        string jsonContent = splittedPromises[j].value.Substring(1, splittedPromises[j].value.Length - 2
 0157                        if (!string.IsNullOrEmpty(jsonContent))
 0158                            json += $",{jsonContent}";
 159                    }
 160
 0161                    promise.Resolve($"[{json}]");
 0162                });
 0163            splittedPromises[i].Catch(error => promise.Reject(error));
 164        }
 165
 0166        return promise;
 167    }
 168
 169    public Promise<string> Get(string url)
 170    {
 0171        Promise<string> promise = new Promise<string>();
 172
 0173        DCL.Environment.i.platform.webRequest.Get(url, null, request =>
 174        {
 0175            promise.Resolve(request.downloadHandler.text);
 0176        }, request =>
 177        {
 0178            promise.Reject($"{request.error} {request.downloadHandler.text} at url {url}");
 0179        });
 180
 0181        return promise;
 182    }
 183
 184    private void PlayerRealmOnOnChange(CurrentRealmModel current, CurrentRealmModel previous)
 185    {
 0186        realmDomain = current.domain;
 0187        realmContentServerUrl = current.contentServerUrl;
 0188    }
 189}