< Summary

Class:RPC.Services.CRDTServiceImpl
Assembly:RPC.Services.CRDTService
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/WorldRuntime/KernelCommunication/RPC/Services/CRDTService/CRDTServiceImpl.cs
Covered lines:26
Uncovered lines:7
Coverable lines:33
Total lines:91
Line coverage:78.7% (26 of 33)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
CRDTServiceImpl()0%110100%
RegisterService(...)0%2100%
SendCrdt()0%13.3412078.95%
PullCrdt(...)0%2.052076.92%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/WorldRuntime/KernelCommunication/RPC/Services/CRDTService/CRDTServiceImpl.cs

#LineLine coverage
 1using System;
 2using System.IO;
 3using System.Threading;
 4using Cysharp.Threading.Tasks;
 5using DCL.CRDT;
 6using Google.Protobuf;
 7using KernelCommunication;
 8using rpc_csharp;
 9using UnityEngine;
 10using BinaryWriter = KernelCommunication.BinaryWriter;
 11
 12namespace RPC.Services
 13{
 14    public class CRDTServiceImpl : ICRDTService<RPCContext>
 15    {
 116        private static readonly CRDTResponse defaultResponse = new CRDTResponse();
 117        private static readonly UniTask<CRDTManyMessages> emptyResponse = UniTask.FromResult(new CRDTManyMessages() { Sc
 18
 119        private static readonly CRDTManyMessages reusableCrdtMessage = new CRDTManyMessages();
 20
 121        private static readonly MemoryStream memoryStream = new MemoryStream();
 122        private static readonly BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
 23
 24        public static void RegisterService(RpcServerPort<RPCContext> port)
 25        {
 026            CRDTServiceCodeGen.RegisterService(port, new CRDTServiceImpl());
 027        }
 28
 29        public async UniTask<CRDTResponse> SendCrdt(CRDTManyMessages messages, RPCContext context, CancellationToken ct)
 30        {
 31            // This line is to avoid a race condition because a CRDT message could be sent before the scene was loaded
 32            // more info: https://github.com/decentraland/sdk/issues/480#issuecomment-1331309908
 1133            await UniTask.WaitUntil(() => context.crdt.MessagingControllersManager.ContainsController(messages.SceneNumb
 34                cancellationToken: ct);
 35
 836            await UniTask.WaitWhile(() => context.crdt.MessagingControllersManager.HasScenePendingMessages(messages.Scen
 37                cancellationToken: ct);
 38
 239            await UniTask.SwitchToMainThread(ct);
 40
 41            try
 42            {
 243                using (var iterator = CRDTDeserializer.DeserializeBatch(messages.Payload.Memory))
 44                {
 445                    while (iterator.MoveNext())
 46                    {
 247                        if (!(iterator.Current is CRDTMessage crdtMessage))
 48                            continue;
 49
 250                        context.crdt.CrdtMessageReceived?.Invoke(messages.SceneNumber, crdtMessage);
 51                    }
 252                }
 253            }
 54            catch (Exception e)
 55            {
 056                Debug.LogError(e);
 057            }
 58
 259            return defaultResponse;
 260        }
 61
 62        public UniTask<CRDTManyMessages> PullCrdt(PullCRDTRequest request, RPCContext context, CancellationToken ct)
 63        {
 64            try
 65            {
 266                if (!context.crdt.scenesOutgoingCrdts.TryGetValue(request.SceneNumber, out CRDTProtocol sceneCrdtState))
 67                {
 068                    return emptyResponse;
 69                }
 70
 271                memoryStream.SetLength(0);
 72
 273                context.crdt.scenesOutgoingCrdts.Remove(request.SceneNumber);
 74
 275                KernelBinaryMessageSerializer.Serialize(binaryWriter, sceneCrdtState);
 276                sceneCrdtState.ClearOnUpdated();
 77
 278                reusableCrdtMessage.SceneId = request.SceneId;
 279                reusableCrdtMessage.SceneNumber = request.SceneNumber;
 280                reusableCrdtMessage.Payload = ByteString.CopyFrom(memoryStream.ToArray());
 81
 282                return UniTask.FromResult(reusableCrdtMessage);
 83            }
 84            catch (Exception e)
 85            {
 086                Debug.LogError(e);
 087                return emptyResponse;
 88            }
 289        }
 90    }
 91}