SpeckleGrasshopper/BaseComponents/GhSenderCoreClient.cs
/// <summary>
/// Sends the update to the server.
/// </summary>
Sends the update to the server.
Sends the update to the server .
private void SendUpdate( )
    {
      if ( MetadataSender.Enabled )
      {
        DataSender.Start();
        return;
      }
      if ( IsSendingUpdate && !DebouncingDisabled )
      {
        return;
      }
      IsSendingUpdate = true;
      var cloneResult = Client.StreamCloneAsync( StreamId ).Result;
      Client.Stream.Children.Add( cloneResult.Clone.StreamId );
      Message = String.Format( "Converting {0} \n objects", BucketObjects.Count );
      var convertedObjects = Converter.Serialise( BucketObjects ).ToList();
      Message = String.Format( "Creating payloads" );
      LocalContext.PruneExistingObjects( convertedObjects, Client.BaseUrl );
      List<SpeckleObject> persistedObjects = new List<SpeckleObject>();
      if ( convertedObjects.Count( obj => obj.Type == "Placeholder" ) != convertedObjects.Count )
      {
        int count = 0;
        var objectUpdatePayloads = new List<List<SpeckleObject>>();
        long totalBucketSize = 0;
        long currentBucketSize = 0;
        var currentBucketObjects = new List<SpeckleObject>();
        var allObjects = new List<SpeckleObject>();
        foreach ( SpeckleObject convertedObject in convertedObjects )
        {
          if ( count++ % 100 == 0 )
          {
            Message = "Converted " + count + " objects out of " + convertedObjects.Count() + ".";
          }
          long size = Converter.getBytes( convertedObject ).Length;
          currentBucketSize += size;
          totalBucketSize += size;
          currentBucketObjects.Add( convertedObject );
          if ( size > 2e6 )
          {
            AddRuntimeMessage( GH_RuntimeMessageLevel.Warning, "This stream contains a super big object. These will fail. Sorry for the bad error message - we're working on improving this." );
            currentBucketObjects.Remove( convertedObject );
          }
          if ( currentBucketSize > 5e5 ) 
          {
            Debug.WriteLine( "Reached payload limit. Making a new one, current  #: " + objectUpdatePayloads.Count );
            objectUpdatePayloads.Add( currentBucketObjects );
            currentBucketObjects = new List<SpeckleObject>();
            currentBucketSize = 0;
          }
        }
        if ( currentBucketObjects.Count > 0 )
        {
          objectUpdatePayloads.Add( currentBucketObjects );
        }
        Debug.WriteLine( "Finished, payload object update count is: " + objectUpdatePayloads.Count + " total bucket size is (kb) " + totalBucketSize / 1000 );
        int k = 0;
        List<ResponseObject> responses = new List<ResponseObject>();
        foreach ( var payload in objectUpdatePayloads )
        {
          Message = String.Format( "{0}/{1}", k++, objectUpdatePayloads.Count );
          try
          {
            var objResponse = Client.ObjectCreateAsync( payload ).Result;
            responses.Add( objResponse );
            persistedObjects.AddRange( objResponse.Resources );
            int m = 0;
            foreach ( var oL in payload )
            {
              oL._id = objResponse.Resources[ m++ ]._id;
            }
            Task.Run( ( ) =>
            {
              foreach ( var oL in payload )
              {
                if ( oL.Type != "Placeholder" )
                {
                  LocalContext.AddSentObject( oL, Client.BaseUrl );
                }
              }
            } );
          }
          catch ( Exception err )
          {
            AddRuntimeMessage( GH_RuntimeMessageLevel.Error, err.Message );
            return;
          }
        }
      }
      else
      {
        persistedObjects = convertedObjects;
      }
      List<SpeckleObject> placeholders = new List<SpeckleObject>();
      foreach ( var obj in persistedObjects )
      {
        placeholders.Add( new SpecklePlaceholder() { _id = obj._id } );
      }
      SpeckleStream updateStream = new SpeckleStream()
      {
        Layers = BucketLayers,
        Name = BucketName,
        Objects = placeholders
      };
      var baseProps = new Dictionary<string, object>();
      baseProps[ "units" ] = Rhino.RhinoDoc.ActiveDoc.ModelUnitSystem.ToString();
      baseProps[ "tolerance" ] = Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance;
      baseProps[ "angleTolerance" ] = Rhino.RhinoDoc.ActiveDoc.ModelAngleToleranceRadians;
      updateStream.BaseProperties = baseProps;
      var response = Client.StreamUpdateAsync( Client.StreamId, updateStream ).Result;
      Client.BroadcastMessage( "stream", Client.StreamId, new { eventType = "update-global" } );
      Log += response.Message;
      AddRuntimeMessage( GH_RuntimeMessageLevel.Remark, "Data sent at " + DateTime.Now );
      Message = "Data sent\n@" + DateTime.Now.ToString( "hh:mm:ss" );
      IsSendingUpdate = false;
      State = "Ok";
    }
private void SendUpdate ( ) { if ( MetadataSender . Enabled ) { DataSender . Start ( ) ; return ; } if ( IsSendingUpdate && ! DebouncingDisabled ) { return ; } IsSendingUpdate = true ; var cloneResult = Client . StreamCloneAsync ( StreamId ) . Result ; Client . Stream . Children . Add ( cloneResult . Clone . StreamId ) ; Message = String . Format ( " \n " , BucketObjects . Count ) ; var convertedObjects = Converter . Serialise ( BucketObjects ) . ToList ( ) ; Message = String . Format ( " " ) ; LocalContext . PruneExistingObjects ( convertedObjects , Client . BaseUrl ) ; List < SpeckleObject > persistedObjects = new List < SpeckleObject > ( ) ; if ( convertedObjects . Count ( obj => obj . Type == " " ) != convertedObjects . Count ) { int count = 0 ; var objectUpdatePayloads = new List < List < SpeckleObject > > ( ) ; long totalBucketSize = 0 ; long currentBucketSize = 0 ; var currentBucketObjects = new List < SpeckleObject > ( ) ; var allObjects = new List < SpeckleObject > ( ) ; foreach ( SpeckleObject convertedObject in convertedObjects ) { if ( count ++ % 100 == 0 ) { Message = " " + count + " " + convertedObjects . Count ( ) + " " ; } long size = Converter . getBytes ( convertedObject ) . Length ; currentBucketSize += size ; totalBucketSize += size ; currentBucketObjects . Add ( convertedObject ) ; if ( size > 2e6 ) { AddRuntimeMessage ( GH_RuntimeMessageLevel . Warning , " " ) ; currentBucketObjects . Remove ( convertedObject ) ; } if ( currentBucketSize > 5e5 ) { Debug . WriteLine ( " " + objectUpdatePayloads . Count ) ; objectUpdatePayloads . Add ( currentBucketObjects ) ; currentBucketObjects = new List < SpeckleObject > ( ) ; currentBucketSize = 0 ; } } if ( currentBucketObjects . Count > 0 ) { objectUpdatePayloads . Add ( currentBucketObjects ) ; } Debug . WriteLine ( " " + objectUpdatePayloads . Count + " " + totalBucketSize / 1000 ) ; int k = 0 ; List < ResponseObject > responses = new List < ResponseObject > ( ) ; foreach ( var payload in objectUpdatePayloads ) { Message = String . Format ( " " , k ++ , objectUpdatePayloads . Count ) ; try { var objResponse = Client . ObjectCreateAsync ( payload ) . Result ; responses . Add ( objResponse ) ; persistedObjects . AddRange ( objResponse . Resources ) ; int m = 0 ; foreach ( var oL in payload ) { oL . _id = objResponse . Resources [ m ++ ] . _id ; } Task . Run ( ( ) => { foreach ( var oL in payload ) { if ( oL . Type != " " ) { LocalContext . AddSentObject ( oL , Client . BaseUrl ) ; } } } ) ; } catch ( Exception err ) { AddRuntimeMessage ( GH_RuntimeMessageLevel . Error , err . Message ) ; return ; } } } else { persistedObjects = convertedObjects ; } List < SpeckleObject > placeholders = new List < SpeckleObject > ( ) ; foreach ( var obj in persistedObjects ) { placeholders . Add ( new SpecklePlaceholder ( ) { _id = obj . _id } ) ; } SpeckleStream updateStream = new SpeckleStream ( ) { Layers = BucketLayers , Name = BucketName , Objects = placeholders } ; var baseProps = new Dictionary < string , object > ( ) ; baseProps [ " " ] = Rhino . RhinoDoc . ActiveDoc . ModelUnitSystem . ToString ( ) ; baseProps [ " " ] = Rhino . RhinoDoc . ActiveDoc . ModelAbsoluteTolerance ; baseProps [ " " ] = Rhino . RhinoDoc . ActiveDoc . ModelAngleToleranceRadians ; updateStream . BaseProperties = baseProps ; var response = Client . StreamUpdateAsync ( Client . StreamId , updateStream ) . Result ; Client . BroadcastMessage ( " " , Client . StreamId , new { eventType = " " } ) ; Log += response . Message ; AddRuntimeMessage ( GH_RuntimeMessageLevel . Remark , " " + DateTime . Now ) ; Message = " \n " + DateTime . Now . ToString ( " " ) ; IsSendingUpdate = false ; State = " " ; }
Sends the update to the server.
Sends the update to the server .
// start the timer again, as we need to make sure we're updating // I believe the expected behaviour for https://github.com/speckleworks/SpeckleRhino/issues/286 // is to send data regardless of wether the previous update was done.  // Hack for thesis: always create history // create the update payloads // size checking & bulk object creation payloads creation // Object is too big? // restrict max to ~500kb; should it be user config? anyway these functions should go into core. at one point.  // add in the last bucket // create bulk object creation tasks // push sent objects in the cache non-blocking // create placeholders for stream update payload //foreach ( var myResponse in responses ) // set some base properties (will be overwritten)