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); } }
/// <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; }