private bool UpdateCache()
        {
            var progress = new Progress <int>();

            progress.ProgressChanged += IncorporateCacheProgress;

            var keywords = GSA.Keywords;

            GSA.App.LocalCache.Clear();

            //initial estimate
            progressEstimator.UpdateTotal(WorkPhase.CacheRead, keywords.Count());
            progressEstimator.UpdateTotal(WorkPhase.CacheUpdate, keywords.Count());
            progressEstimator.UpdateTotal(WorkPhase.Conversion, 10000); //Take wild guess at having 10,000 objects to convert
            progressEstimator.UpdateTotal(WorkPhase.ApiCalls, 10);      //Take wild guess at having 10 API calls to make

            try
            {
                var data = GSA.App.Proxy.GetGwaData(keywords, false, progress);
                progressEstimator.UpdateTotal(WorkPhase.CacheRead, data.Count());
                progressEstimator.SetCurrentToTotal(WorkPhase.CacheRead); //Equalise the current and total in case the previous total estimate was wrong

                //Now that we have a better ideaof how many objects to update the cache with, and convert
                progressEstimator.UpdateTotal(WorkPhase.CacheUpdate, data.Count());
                progressEstimator.UpdateTotal(WorkPhase.Conversion, data.Count());

                for (int i = 0; i < data.Count(); i++)
                {
                    var applicationId = (string.IsNullOrEmpty(data[i].ApplicationId)) ? null : data[i].ApplicationId;
                    GSA.App.LocalCache.Upsert(
                        data[i].Keyword,
                        data[i].Index,
                        data[i].GwaWithoutSet,
                        streamId: data[i].StreamId,
                        applicationId: applicationId,
                        gwaSetCommandType: data[i].GwaSetType);

                    progressEstimator.AppendCurrent(WorkPhase.CacheRead, 1);
                }

                int numRowsupdated = data.Count();
                if (numRowsupdated > 0)
                {
                    loggingProgress.Report(new MessageEventArgs(SpeckleGSAInterfaces.MessageIntent.Display, SpeckleGSAInterfaces.MessageLevel.Information,
                                                                "Read " + numRowsupdated + " GWA lines across " + keywords.Count() + " keywords into cache"));
                }

                progressEstimator.SetCurrentToTotal(WorkPhase.CacheUpdate); //Equalise the current and total in case the previous total estimate was wrong

                return(true);
            }
            catch
            {
                return(false);
            }
        }
Beispiel #2
0
    /// <summary>
    /// Trigger to update stream. Is called automatically when update-global ws message is received on stream.
    /// </summary>
    public void Trigger(object sender, EventArgs e)
    {
      if ((IsBusy) || (!IsInit)) return;

      IsBusy = true;

      var startTime = DateTime.Now;

      //GSA.App.Settings.Units = GSA.App.Proxy.GetUnits();

      lock (traversedSerialisedLock)
      {
        traversedSerialisedTypes.Clear();
      }
      lock (traversedDeserialisedLock)
      {
        traversedDeserialisedTypes.Clear();
      }

      GSA.SenderDictionaries.Clear();

      // Read objects
      statusProgress.Report("Receiving streams");

      var streamIds = StreamReceivers.Keys.ToList();

      var rxObjsByStream = new Dictionary<string, List<SpeckleObject>>();

      foreach (var streamId in StreamReceivers.Keys)
      {
        rxObjsByStream.Add(streamId, StreamReceivers[streamId].GetObjects());  //This calls UpdateGlobal(), which is the trigger for pulilng information from the server
        progressEstimator.AppendCurrent(WorkPhase.ApiCalls, 1);
      }

      progressEstimator.UpdateTotal(WorkPhase.Conversion, rxObjsByStream.Keys.Sum(k => rxObjsByStream[k].Count()));

      //This list will contain ALL speckle objects received across all streams
      var rxObjs = new List<SpeckleObject>();
      var units = GSA.GsaApp.Settings.Units;
      foreach (var streamId in StreamReceivers.Keys)
      {
        double factor = 1;
        if (StreamReceivers[streamId].Units == null)
        {
          //Let the user know if any streams have no unit information
          this.loggingProgress.Report(new MessageEventArgs(MessageIntent.Display, MessageLevel.Error, "Streams with no unit information", streamId));
        }
        else
        {
          factor = (1.0).ConvertUnit(StreamReceivers[streamId].Units.ShortUnitName(), units);
        }
        foreach (var o in rxObjsByStream[streamId])
        {
          if (string.IsNullOrEmpty(o.ApplicationId))
          {
            this.loggingProgress.Report(new MessageEventArgs(MessageIntent.Display, MessageLevel.Information, o.GetType().Name + ((string.IsNullOrEmpty(o.Name))
              ? " with no name nor ApplicationId (identified by hashes)" : " with no name nor ApplicationId (identified by hashes)"), o.Hash));
          }
          else
          {
            o.Properties.Add("StreamId", streamId);

            try
            {
              o.Scale(factor);
            }
            catch (Exception ex)
            {
              this.loggingProgress.Report(new MessageEventArgs(MessageIntent.Display, MessageLevel.Error, "Scaling issue for objects with _ids on stream: " + streamId, o._id));
              this.loggingProgress.Report(new MessageEventArgs(MessageIntent.TechnicalLog, MessageLevel.Error, ex, "Scaling issue", "StreamId=" + streamId, "_id=" + o._id));
            }

            //Populate the cache with stream IDs - review if this is needed anymroe
            GSA.App.LocalCache.SetStream(o.ApplicationId, streamId);
            rxObjs.Add(o);
          }
        }
      }

      progressEstimator.UpdateTotal(WorkPhase.Conversion, rxObjs.Count());

      //GSA.App.Messenger.Trigger();

      TimeSpan duration = DateTime.Now - startTime;
      this.loggingProgress.Report(new MessageEventArgs(MessageIntent.Display, MessageLevel.Information, "Duration of reception from Speckle and scaling: " + duration.ToString(@"hh\:mm\:ss")));
      this.loggingProgress.Report(new MessageEventArgs(MessageIntent.Telemetry, MessageLevel.Information, "receive", "reception and scaling", "duration", duration.ToString(@"hh\:mm\:ss")));

      if (rxObjs.Count() == 0)
      {
        this.loggingProgress.Report(new MessageEventArgs(MessageIntent.Display, MessageLevel.Information, "No processing needed because the stream(s) contain(s) no objects"));
        statusProgress.Report("Finished receiving");
        IsBusy = false;
        return;
      }

      startTime = DateTime.Now;
      streamIds.ForEach(s => GSA.App.LocalCache.Snapshot(s));

      ProcessRxObjects(rxObjs);

      var toBeAddedGwa = GSA.App.LocalCache.GetNewGwaSetCommands();
      toBeAddedGwa.ForEach(tba => GSA.App.Proxy.SetGwa(tba));

      var toBeDeletedGwa = GSA.App.LocalCache.GetExpiredData();

      var setDeletes = toBeDeletedGwa.Where(t => t.Item4 == GwaSetCommandType.Set).ToList();
      setDeletes.ForEach(sd => GSA.App.Proxy.DeleteGWA(sd.Item1, sd.Item2, GwaSetCommandType.Set));

      var setAtDeletes = toBeDeletedGwa.Where(t => t.Item4 == GwaSetCommandType.SetAt).OrderByDescending(t => t.Item2).ToList();
      setAtDeletes.ForEach(sad => GSA.App.Proxy.DeleteGWA(sad.Item1, sad.Item2, GwaSetCommandType.SetAt));

      GSA.App.Proxy.Sync();

      GSA.App.Proxy.UpdateCasesAndTasks();
      GSA.App.Proxy.UpdateViews();

      duration = DateTime.Now - startTime;
      this.loggingProgress.Report(new MessageEventArgs(MessageIntent.Display, MessageLevel.Information, "Duration of conversion from Speckle: " + duration.ToString(@"hh\:mm\:ss")));
      this.loggingProgress.Report(new MessageEventArgs(MessageIntent.Telemetry, MessageLevel.Information, "receive", "conversion", "duration", duration.ToString(@"hh\:mm\:ss")));
      startTime = DateTime.Now;

      statusProgress.Report("Finished receiving");
      IsBusy = false;
    }