Skip to content

Commit

Permalink
[WIP] Implement PitayaMetrics class
Browse files Browse the repository at this point in the history
  • Loading branch information
Luiz Felipe Takakura committed Dec 3, 2019
1 parent 98425d9 commit 1a8f321
Show file tree
Hide file tree
Showing 3 changed files with 195 additions and 7 deletions.
22 changes: 16 additions & 6 deletions unity/PitayaExample/Assets/Pitaya/PitayaClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public class PitayaClient : IDisposable, IPitayaListener
private const int DEFAULT_CONNECTION_TIMEOUT = 30;

private IntPtr _client = IntPtr.Zero;
private PitayaMetrics _metricsAggr;
private EventManager _eventManager;
private bool _disposed;
private uint _reqUid;
Expand All @@ -22,35 +23,41 @@ public class PitayaClient : IDisposable, IPitayaListener

public PitayaClient()
{
Init(null, false, false, false, DEFAULT_CONNECTION_TIMEOUT);
Init(null, false, false, false, DEFAULT_CONNECTION_TIMEOUT, null);
}

public PitayaClient(int connectionTimeout)
{
Init(null, false, false, false, connectionTimeout);
Init(null, false, false, false, connectionTimeout, null);
}

public PitayaClient(string certificateName = null)
{
Init(certificateName, certificateName != null, false, false, DEFAULT_CONNECTION_TIMEOUT);
Init(certificateName, certificateName != null, false, false, DEFAULT_CONNECTION_TIMEOUT, null);
}

public PitayaClient(bool enableReconnect = false, string certificateName = null, int connectionTimeout = DEFAULT_CONNECTION_TIMEOUT)
public PitayaClient(PitayaMetrics.MetricsCallback metricsCB = null)
{
Init(certificateName, certificateName != null, false, enableReconnect, DEFAULT_CONNECTION_TIMEOUT);
Init(null, false, false, false, DEFAULT_CONNECTION_TIMEOUT, metricsCB);
}

public PitayaClient(bool enableReconnect = false, string certificateName = null, int connectionTimeout = DEFAULT_CONNECTION_TIMEOUT, PitayaMetrics.MetricsCallback metricsCB = null)
{
Init(certificateName, certificateName != null, false, enableReconnect, DEFAULT_CONNECTION_TIMEOUT, metricsCB);
}

~PitayaClient()
{
Dispose();
}

private void Init(string certificateName, bool enableTlS, bool enablePolling, bool enableReconnect, int connTimeout)
private void Init(string certificateName, bool enableTlS, bool enablePolling, bool enableReconnect, int connTimeout, PitayaMetrics.MetricsCallback metricsCB)
{
_eventManager = new EventManager();
_typeRequestSubscriber = new TypeSubscriber<uint>();
_typePushSubscriber = new TypeSubscriber<string>();
_client = PitayaBinding.CreateClient(enableTlS, enablePolling, enableReconnect, connTimeout, this);
_metricsAggr = new PitayaMetrics(metricsCB);

if (certificateName != null)
{
Expand Down Expand Up @@ -83,11 +90,13 @@ public PitayaClientState State

public void Connect(string host, int port, string handshakeOpts = null)
{
_metricsAggr.Start();
PitayaBinding.Connect(_client, host, port, handshakeOpts);
}

public void Connect(string host, int port, Dictionary<string, string> handshakeOpts)
{
_metricsAggr.Start();
var opts = Pitaya.SimpleJson.SimpleJson.SerializeObject(handshakeOpts);
PitayaBinding.Connect(_client, host, port, opts);
}
Expand Down Expand Up @@ -208,6 +217,7 @@ public void OnRequestError(uint rid, PitayaError error)
public void OnNetworkEvent(PitayaNetWorkState state, NetworkError error)
{
if(NetWorkStateChangedEvent != null ) NetWorkStateChangedEvent.Invoke(state, error);
_metricsAggr.Update(state, error);
}

public void OnUserDefinedPush(string route, byte[] serializedBody)
Expand Down
172 changes: 172 additions & 0 deletions unity/PitayaExample/Assets/Pitaya/PitayaMetrics.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.IO;
using Google.Protobuf;
using UnityEngine;
using System.Linq;

namespace Pitaya
{
public class PitayaMetrics
{
public ConnectionSessionStats connectionSessionStats;
public delegate void MetricsCallback(ConnectionSessionStats stats);
private Stopwatch connectionWatch = new Stopwatch();
private Stopwatch sessionWatch = new Stopwatch();
private MetricsCallback cb;

public enum ConnectionFailure
{
CouldNotResolveHost,
Error,
Timeout,
}

private static class disconnectionReason
{
public const string ConnectionEndedNormally = "ConnectionEndedNormally";
public const string ConnectionTimeout = "ConnectionTimeout";
public const string FailedToConnect = "FailedToConnect";
public const string ConnectionErrored = "ConnectionErrored";
public const string ConnectionClosed = "ConnectionClosed";
public const string ConnectionKicked = "Kicked";
}

private PitayaNetWorkState[] sessionStartedStates = {
PitayaNetWorkState.Connected, PitayaNetWorkState.FailToConnect, PitayaNetWorkState.Timeout, PitayaNetWorkState.Error
};

private PitayaNetWorkState[] sessionErroredStates = {
PitayaNetWorkState.FailToConnect, PitayaNetWorkState.Timeout, PitayaNetWorkState.Error
};

private PitayaNetWorkState[] sessionEndStates = {
PitayaNetWorkState.Disconnected, PitayaNetWorkState.Kicked, PitayaNetWorkState.Closed
};

public struct PingStats
{
public uint Average;
public uint StandardDeviation;
public uint Loss;
}

public struct ConnectionSessionStats
{
public uint Version;
public TimeSpan? SessionDurationSec;
public PingStats? Ping;
public string DisconnectionReason;
public ConnectionFailure ConnectionFailure;
public string ConnectionFailureDetails;
public TimeSpan ConnectionTime;
public string ConnectionRegion;
public Dictionary<string, TimeSpan> RoutesLatency;
public Dictionary<string, TimeSpan> RoutesStandardDeviation;
public string NetworkType;
public string LibPitayaVersion;
}

public PitayaMetrics(MetricsCallback metricsCB = null)
{
cb = metricsCB;
}

public void Start()
{
connectionSessionStats = new ConnectionSessionStats();
sessionWatch.Start();
connectionWatch.Start();
}

public void Update(PitayaNetWorkState state, NetworkError error)
{
// Session started
if (sessionStartedStates.Contains(state))
{
connectionWatch.Stop();
connectionSessionStats.ConnectionTime = connectionWatch.Elapsed;
}

// Session ended
if (sessionEndStates.Contains(state) || sessionErroredStates.Contains(state))
{
stop(state, error);
}
}

private void stop(PitayaNetWorkState state=PitayaNetWorkState.Disconnected, NetworkError error=null)
{
sessionWatch.Stop();
connectionSessionStats.SessionDurationSec = sessionWatch.Elapsed;
setDisconnectionReason(state, error);

if (cb != null)
{
cb(connectionSessionStats);
}
}

private void setDisconnectionReason(PitayaNetWorkState state, NetworkError error)
{
if (state == PitayaNetWorkState.Disconnected)
{
// Disconnected with errors
if (error != null) {
connectionSessionStats.DisconnectionReason = error.Error;
return;
}

// Disconnected normally
connectionSessionStats.DisconnectionReason = disconnectionReason.ConnectionEndedNormally;
return;
}

// Timeout trying to connect
if (state == PitayaNetWorkState.Timeout)
{
connectionSessionStats.DisconnectionReason = disconnectionReason.ConnectionTimeout;
connectionSessionStats.ConnectionFailure = ConnectionFailure.Timeout;
if (error != null) {
connectionSessionStats.ConnectionFailureDetails = error.Error;
}
return;
}

// Disconnected due to errors
if (state == PitayaNetWorkState.Error || state == PitayaNetWorkState.FailToConnect)
{
connectionSessionStats.ConnectionFailure = ConnectionFailure.Error;
connectionSessionStats.DisconnectionReason = disconnectionReason.ConnectionErrored;

if (state == PitayaNetWorkState.FailToConnect)
{
connectionSessionStats.DisconnectionReason = disconnectionReason.FailedToConnect;
}

// Error string is set
if (error != null) {
connectionSessionStats.ConnectionFailureDetails = error.Error;
return;
}

return;
}

// Closed connection
if (state == PitayaNetWorkState.Closed)
{
connectionSessionStats.DisconnectionReason = disconnectionReason.ConnectionClosed;
return;
}

// Kicked
if (state == PitayaNetWorkState.Kicked)
{
connectionSessionStats.DisconnectionReason = disconnectionReason.ConnectionKicked;
return;
}
}
}
}
8 changes: 7 additions & 1 deletion unity/PitayaExample/Assets/Tests/PitayaClientTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class PitayaClientTest
public void Setup()
{
_mainThread = Thread.CurrentThread;
_client = new PitayaClient();
_client = new PitayaClient(metricsCallbackFunc);
}

[TearDown]
Expand All @@ -31,6 +31,12 @@ public void TearDown()
_client = null;
}

private void metricsCallbackFunc(PitayaMetrics.ConnectionSessionStats connectionSessionStats)
{
UnityEngine.Debug.Log(string.Format("** REPORT **\n SessionTime = {0} | ConnectionTime = {1} | DisconnectionReason = {2} | ConnectionFailureDetails = {3}",
connectionSessionStats.SessionDurationSec, connectionSessionStats.ConnectionTime, connectionSessionStats.DisconnectionReason, connectionSessionStats.ConnectionFailureDetails));
}

[Test]
public void ShouldCreateClient()
{
Expand Down

0 comments on commit 1a8f321

Please sign in to comment.