Skip to content
This repository has been archived by the owner on Aug 28, 2021. It is now read-only.

Commit

Permalink
Merge pull request #134 from speckleworks/dimitrie/dev/telemetrry
Browse files Browse the repository at this point in the history
Dimitrie/dev/telemetrry
  • Loading branch information
didimitrie committed Sep 23, 2019
2 parents e0670aa + a800bb8 commit ba05c4a
Show file tree
Hide file tree
Showing 18 changed files with 589 additions and 170 deletions.
27 changes: 18 additions & 9 deletions ApiClient/SpeckleApiClientApiCalls.cs
Original file line number Diff line number Diff line change
Expand Up @@ -395,11 +395,11 @@ public async System.Threading.Tasks.Task<ResponseUser> UserGetAsync( System.Thre
}
}
}
catch (TaskCanceledException)
catch ( TaskCanceledException )
{
throw new SpeckleException("Connection timeout with Speckle Server", (int)HttpStatusCode.RequestTimeout, null, null, null);
throw new SpeckleException( "Connection timeout with Speckle Server", ( int ) HttpStatusCode.RequestTimeout, null, null, null );
}
finally
finally
{
if ( client_ != null )
client_.Dispose();
Expand Down Expand Up @@ -2217,6 +2217,9 @@ public System.Threading.Tasks.Task<ResponseStream> StreamCreateAsync( SpeckleStr
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
public async System.Threading.Tasks.Task<ResponseStream> StreamCreateAsync( SpeckleStream stream, System.Threading.CancellationToken cancellationToken )
{

SpeckleTelemetry.RecordStreamCreated( ClientType );

var urlBuilder_ = new System.Text.StringBuilder();
urlBuilder_.Append( BaseUrl != null ? BaseUrl.TrimEnd( '/' ) : "" ).Append( "/streams" );

Expand Down Expand Up @@ -2317,6 +2320,9 @@ public System.Threading.Tasks.Task<ResponseStream> StreamGetAsync( string stream
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
public async System.Threading.Tasks.Task<ResponseStream> StreamGetAsync( string streamId, string query, System.Threading.CancellationToken cancellationToken )
{

SpeckleTelemetry.RecordStreamReceived( ClientType );

if ( streamId == null )
throw new System.ArgumentNullException( "streamId" );

Expand Down Expand Up @@ -2396,11 +2402,11 @@ public async System.Threading.Tasks.Task<ResponseStream> StreamGetAsync( string
}
}
}
catch (TaskCanceledException)
catch ( TaskCanceledException )
{
throw new SpeckleException("Connection timeout with Speckle Server", (int)HttpStatusCode.RequestTimeout, null, null, null);
throw new SpeckleException( "Connection timeout with Speckle Server", ( int ) HttpStatusCode.RequestTimeout, null, null, null );
}
finally
finally
{
if ( client_ != null )
client_.Dispose();
Expand All @@ -2421,6 +2427,9 @@ public System.Threading.Tasks.Task<ResponseBase> StreamUpdateAsync( string strea
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
public async System.Threading.Tasks.Task<ResponseBase> StreamUpdateAsync( string streamId, SpeckleStream stream, System.Threading.CancellationToken cancellationToken )
{

SpeckleTelemetry.RecordStreamUpdated( ClientType );

if ( streamId == null )
throw new System.ArgumentNullException( "streamId" );

Expand Down Expand Up @@ -2697,9 +2706,9 @@ public async System.Threading.Tasks.Task<ResponseObject> StreamGetObjectsAsync(

return default( ResponseObject );
}
catch (TaskCanceledException)
catch ( TaskCanceledException )
{
throw new SpeckleException("Connection timeout with Speckle server", (int) HttpStatusCode.RequestTimeout, null, null, null);
throw new SpeckleException( "Connection timeout with Speckle server", ( int ) HttpStatusCode.RequestTimeout, null, null, null );
}
finally
{
Expand Down Expand Up @@ -3425,7 +3434,7 @@ public async System.Threading.Tasks.Task<ResponseObject> ObjectGetBulkAsync( str
if ( query != null ) urlBuilder_.Append( query );


var client_ = GetHttpClient(defaultBulkTimeoutMilliseconds);
var client_ = GetHttpClient( defaultBulkTimeoutMilliseconds );
try
{
using ( var request_ = new System.Net.Http.HttpRequestMessage() )
Expand Down
93 changes: 54 additions & 39 deletions ApiClient/SpeckleApiClientExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,13 @@ public partial class SpeckleApiClient : ISerializable

private Dictionary<string, SpeckleObject> ObjectCache = new Dictionary<string, SpeckleObject>();

// stores the client type: Grasshopper, Revit, etc.
public string ClientType { get; set; }

public SpeckleApiClient( string baseUrl, bool isPersistent = false )
public SpeckleApiClient( string baseUrl, bool isPersistent = false, string documentType = "unknown" )
{
ClientType = documentType;

SetSerialisationSettings();

BaseUrl = baseUrl;
Expand All @@ -72,20 +76,21 @@ public SpeckleApiClient( string baseUrl, bool isPersistent = false )
SetReadyTimer();
}

public SpeckleApiClient( bool useGzip = true )
public SpeckleApiClient( bool useGzip = true, string documentType = "unknown" )
{
ClientType = documentType;
SetSerialisationSettings();
UseGzip = useGzip;
}

public SpeckleApiClient()
public SpeckleApiClient( )
{
SetSerialisationSettings();
}

private void SetSerialisationSettings()
private void SetSerialisationSettings( )
{
_settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>( () =>
_settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>( ( ) =>
{
var settings = new Newtonsoft.Json.JsonSerializerSettings()
{
Expand All @@ -109,7 +114,9 @@ private void SetSerialisationSettings()
/// <returns></returns>
public async Task IntializeReceiver( string streamId, string documentName, string documentType, string documentGuid, string authToken = null )
{
if( Role != null )
ClientType = documentType;

if ( Role != null )
throw new Exception( "Role changes are not permitted. Maybe create a new client?" );

Role = ClientRole.Receiver;
Expand All @@ -118,26 +125,25 @@ public async Task IntializeReceiver( string streamId, string documentName, strin
try
{
AuthToken = authToken;
User = (await this.UserGetAsync()).Resource;
User = ( await this.UserGetAsync() ).Resource;

}
catch( SpeckleException e )
catch ( SpeckleException e )
{
OnError?.Invoke( this, new SpeckleEventArgs() { EventName = e.StatusCode.ToString(), EventData = e.Message } );
}

try
{
Stream = (await this.StreamGetAsync( streamId, null )).Resource;
Stream = ( await this.StreamGetAsync( streamId, null ) ).Resource;
await SetupClient( documentName, documentType, documentGuid );
SetupWebsocket();
}
catch( SpeckleException e )
catch ( SpeckleException e )
{
OnError?.Invoke( this, new SpeckleEventArgs() { EventName = e.StatusCode.ToString(), EventData = e.Message } );
}


}
/// <summary>
/// Initialises this client as a Sender by creating a new stream.
Expand All @@ -149,49 +155,50 @@ public async Task IntializeReceiver( string streamId, string documentName, strin
/// <returns></returns>
public async Task<string> IntializeSender( string authToken, string documentName, string documentType, string documentGuid )
{
if( Role != null )
ClientType = documentType;

if ( Role != null )
throw new Exception( "Role changes are not permitted. Maybe create a new client?" );

Role = ClientRole.Sender;

try
{
AuthToken = authToken;
User = (await this.UserGetAsync()).Resource;
User = ( await this.UserGetAsync() ).Resource;
}
catch( SpeckleException e )
catch ( SpeckleException e )
{
OnError?.Invoke( this, new SpeckleEventArgs() { EventName = "error", EventData = "Could not log in: " + e.Message } );
return null;
}

try
{
Stream = (await this.StreamCreateAsync( new SpeckleStream() )).Resource;
Stream = ( await this.StreamCreateAsync( new SpeckleStream() ) ).Resource;
StreamId = Stream.StreamId;

await SetupClient( documentName, documentType, documentGuid );
SetupWebsocket();

return Stream.StreamId;
}
catch( SpeckleException e )
catch ( SpeckleException e )
{
OnError?.Invoke( this, new SpeckleEventArgs() { EventName = e.StatusCode.ToString(), EventData = e.Message } );

return null;
}

}

private async Task SetupClient( string documentName = null, string documentType = null, string documentGuid = null )
{
if( ClientId == null )
if ( ClientId == null )
{
LogEvent( "Creating a new client." );
var myClient = new AppClient() { StreamId = StreamId, Role = Role.ToString(), Online = true, DocumentGuid = documentGuid, DocumentName = documentName, DocumentType = documentType };

ClientId = (await this.ClientCreateAsync( myClient )).Resource._id;
ClientId = ( await this.ClientCreateAsync( myClient ) ).Resource._id;
}
else
{
Expand All @@ -205,38 +212,38 @@ private void LogEvent( string what )
OnLogData?.Invoke( this, new SpeckleEventArgs() { EventData = what } );
}

private void SetReadyTimer()
private void SetReadyTimer( )
{
IsReady = new Timer( 200 ) { AutoReset = false, Enabled = true };
IsReady.Elapsed += ( sender, e ) =>
{
LogEvent( "Checking readiness..." );
if( StreamId == null || ClientId == null || WsConnected == false ) { IsReady.Start(); return; }
if ( StreamId == null || ClientId == null || WsConnected == false ) { IsReady.Start(); return; }
OnReady?.Invoke( this, new SpeckleEventArgs() { EventName = "client-ready" } );
IsConnected = true;
LogEvent( "Client is ready!" );
};
}

private void SetWsReconnectTimer()
private void SetWsReconnectTimer( )
{
WsReconnecter = new Timer( 1000 ) { AutoReset = false, Enabled = false };
WsReconnecter.Elapsed += ( sender, e ) =>
{
if( IsDisposed ) return;
if ( IsDisposed ) return;
WebsocketClient.Connect();
};
}

/// <summary>
/// Sets up the websocket client & its events..
/// </summary>
public void SetupWebsocket()
public void SetupWebsocket( )
{
SetWsReconnectTimer();

//generates a random guid
if( ClientId == null )
if ( ClientId == null )
ClientId = Guid.NewGuid().ToString();

WebsocketClient = new WebSocket( BaseUrl.Replace( "http", "ws" ) + "?access_token=" + AuthToken + "&stream_id=" + StreamId + "&client_id=" + ClientId );
Expand All @@ -256,7 +263,7 @@ public void SetupWebsocket()

WebsocketClient.OnMessage += ( sender, e ) =>
{
if( e.Data == "ping" ) { WebsocketClient.Send( "alive" ); LogEvent( "Got a ws ping." ); return; }
if ( e.Data == "ping" ) { WebsocketClient.Send( "alive" ); LogEvent( "Got a ws ping." ); return; }
LogEvent( "Got a ws message." );
try
Expand All @@ -283,7 +290,7 @@ public void SetupWebsocket()
/// <param name="args">What you want to send. Make it serialisable and small.</param>
public void SendMessage( string receipientId, dynamic args )
{
if( !WsConnected )
if ( !WsConnected )
{
OnError?.Invoke( this, new SpeckleEventArgs() { EventName = "Websocket client not connected.", EventData = "Websocket client not connected." } );
return;
Expand All @@ -309,7 +316,7 @@ public void SendMessage( string receipientId, dynamic args )
/// <param name="args">The message. Make it serialisable and small.</param>
public void BroadcastMessage( string resourceType, string resourceId, dynamic args )
{
if( !WsConnected )
if ( !WsConnected )
{
OnError?.Invoke( this, new SpeckleEventArgs() { EventName = "Websocket client not connected.", EventData = "Websocket client not connected." } );
return;
Expand All @@ -334,7 +341,7 @@ public void BroadcastMessage( string resourceType, string resourceId, dynamic ar
/// <param name="resourceId">The database id of the resource.</param>
public void JoinRoom( string resourceType, string resourceId )
{
if( !WsConnected )
if ( !WsConnected )
{
OnError?.Invoke( this, new SpeckleEventArgs() { EventName = "Websocket client not connected.", EventData = "Websocket client not connected." } );
return;
Expand All @@ -358,7 +365,7 @@ public void JoinRoom( string resourceType, string resourceId )
/// <param name="resourceId">The database id of the resource.</param>
public void LeaveRoom( string resourceType, string resourceId )
{
if( !WsConnected )
if ( !WsConnected )
{
OnError?.Invoke( this, new SpeckleEventArgs() { EventName = "Websocket client not connected.", EventData = "Websocket client not connected." } );
return;
Expand All @@ -381,7 +388,7 @@ public void LogError( SpeckleException err )

protected SpeckleApiClient( SerializationInfo info, StreamingContext context )
{
_settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>( () =>
_settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>( ( ) =>
{
var settings = new Newtonsoft.Json.JsonSerializerSettings()
{
Expand All @@ -396,18 +403,27 @@ protected SpeckleApiClient( SerializationInfo info, StreamingContext context )

BaseUrl = info.GetString( "BaseUrl" );
StreamId = info.GetString( "StreamId" );
Role = (ClientRole) info.GetInt32( "Role" );
Role = ( ClientRole ) info.GetInt32( "Role" );
ClientId = info.GetString( "ClientId" );

//AuthToken = info.GetString( "ApiToken" );
//string userEmail = null;
try
{
ClientType = info.GetString( "ClientType" );
}
catch ( Exception e )
{
// Meep, no client type present. old client.
// NOTE: the end clients (rhino, grasshopper, dynamo, etc) should attempt to set this value again on their re-initialisation.
// This is so that we can actually get types out for pre-existing clients that didn't save the ClientType property.
ClientType = "undefined";
}

// old clients will not have a user email field :/
try
{
var userEmail = info.GetString( "UserEmail" );
var acc = LocalContext.GetAccountByEmailAndRestApi( userEmail, BaseUrl );
if( acc != null )
if ( acc != null )
{
AuthToken = acc.Token;
User = new User() { Email = acc.Email };
Expand All @@ -421,7 +437,7 @@ protected SpeckleApiClient( SerializationInfo info, StreamingContext context )
{
var accs = LocalContext.GetAccountsByRestApi( BaseUrl );
var sorted = accs.OrderByDescending( acc => acc.IsDefault ).ToList();
if( sorted.Count == 0 )
if ( sorted.Count == 0 )
{
throw new Exception( "You do not have an account that matches this stream's server." );
}
Expand Down Expand Up @@ -449,15 +465,14 @@ public void GetObjectData( SerializationInfo info, StreamingContext context )
info.AddValue( "StreamId", StreamId );
info.AddValue( "Role", Role );
info.AddValue( "ClientId", ClientId );

//info.AddValue( "ApiToken", AuthToken );
info.AddValue( "ClientType", ClientType );
}

public void Dispose( bool delete = false )
{
IsDisposed = true;

if( !delete )
if ( !delete )
{
ClientUpdateAsync( ClientId, new AppClient() { Online = false } );
WebsocketClient?.Close();
Expand Down
4 changes: 2 additions & 2 deletions ApiClient/SpeckleApiClientHead.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@

using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.IO.Compression;
using System.IO;
using System.Text;


namespace SpeckleCore
{
[System.CodeDom.Compiler.GeneratedCode( "NSwag", "11.3.3.0" )]
Expand Down
Loading

0 comments on commit ba05c4a

Please sign in to comment.