/// <summary> /// Initializes sender. /// </summary> /// <param name="restApi">Server address</param> /// <param name="apiToken">API token of account</param> /// <returns>Task</returns> public async Task <List <string> > Initialize(string restApi, string apiToken, Func <string, string, ISpeckleGSASender> gsaSenderCreator) { var statusMessages = new List <string>(); if (IsInit) { return(statusMessages); } if (!GSA.IsInit) { Status.AddError("GSA link not found."); return(statusMessages); } GSA.SetAssembliesSenderDictionaries(); var startTime = DateTime.Now; Status.ChangeStatus("Reading GSA data into cache"); //Update cache int numRowsUpdated = 0; int numKeywords = 0; var updatedCache = await Task.Run(() => UpdateCache(out numRowsUpdated, out numKeywords)); if (!updatedCache) { Status.AddError("Error in communicating GSA - please check if the GSA file has been closed down"); return(statusMessages); } Status.AddMessage("Read " + numRowsUpdated + " GWA lines across " + numKeywords + " keywords into cache"); // Grab all GSA related object Status.ChangeStatus("Preparing to read GSA Objects"); // Run initialize sender method in interfacer var objTypes = GetAssembliesTypes(); var streamNames = GetStreamNames(objTypes); CreateStreamMap(objTypes); // Create the streams Status.ChangeStatus("Creating streams"); await CreateInitialiseSenders(streamNames, gsaSenderCreator, restApi, apiToken); TimeSpan duration = DateTime.Now - startTime; Status.AddMessage("Duration of initialisation: " + duration.ToString(@"hh\:mm\:ss")); Status.ChangeStatus("Ready to stream"); IsInit = true; return(statusMessages); }
private Dictionary <string, Dictionary <string, List <SpeckleObject> > > CreateStreamBuckets() { var buckets = new Dictionary <string, Dictionary <string, List <SpeckleObject> > >(); var currentObjects = GSA.GetAllConvertedGsaObjectsByType(); foreach (var t in currentObjects.Keys) { //var bucketName = GSA.App.Settings.SeparateStreams ? StreamMap[kvp.Key] : "Full Model"; var bucketName = (string)t.GetAttribute("Stream"); foreach (IGSASpeckleContainer obj in currentObjects[t]) { if (GSA.App.LocalSettings.SendOnlyMeaningfulNodes) { if (obj.GetType().Name == "GSANode" && !(bool)obj.GetType().GetField("ForceSend").GetValue(obj)) { continue; } } var insideVal = (SpeckleObject)obj.SpeckleObject; insideVal.GenerateHash(); if (!buckets.ContainsKey(bucketName)) { buckets[bucketName] = new Dictionary <string, List <SpeckleObject> >(); } if (buckets[bucketName].ContainsKey(insideVal.GetType().Name)) { buckets[bucketName][insideVal.GetType().Name].Add(insideVal); } else { buckets[bucketName][insideVal.GetType().Name] = new List <SpeckleObject>() { insideVal }; } } } return(buckets); }
private Dictionary <string, Dictionary <string, List <object> > > CreateStreamBuckets() { var streamBuckets = new Dictionary <string, Dictionary <string, List <object> > >(); var currentObjects = GSA.GetAllConvertedGsaObjectsByType(); foreach (var kvp in currentObjects) { var targetStream = GSA.Settings.SeparateStreams ? StreamMap[kvp.Key] : "Full Model"; foreach (object obj in kvp.Value) { if (GSA.Settings.SendOnlyMeaningfulNodes) { if (obj.GetType().Name == "GSANode" && !(bool)obj.GetType().GetField("ForceSend").GetValue(obj)) { continue; } } object insideVal = obj.GetType().GetProperty("Value").GetValue(obj); ((SpeckleObject)insideVal).GenerateHash(); if (!streamBuckets.ContainsKey(targetStream)) { streamBuckets[targetStream] = new Dictionary <string, List <object> >(); } if (streamBuckets[targetStream].ContainsKey(insideVal.GetType().Name)) { streamBuckets[targetStream][insideVal.GetType().Name].Add(insideVal); } else { streamBuckets[targetStream][insideVal.GetType().Name] = new List <object>() { insideVal }; } } } return(streamBuckets); }
private async Task CreateInitialiseSenders(List <string> streamNames, Func <string, string, ISpeckleGSASender> GSASenderCreator, string restApi, string apiToken) { GSA.RemoveUnusedStreamInfo(streamNames); Senders = new Dictionary <string, ISpeckleGSASender>(); foreach (string streamName in streamNames) { Senders[streamName] = GSASenderCreator(restApi, apiToken); if (!GSA.SenderInfo.ContainsKey(streamName)) { Status.AddMessage("Creating new sender for " + streamName); await Senders[streamName].InitializeSender(null, null, streamName); GSA.SenderInfo[streamName] = new Tuple <string, string>(Senders[streamName].StreamID, Senders[streamName].ClientID); } else { await Senders[streamName].InitializeSender(GSA.SenderInfo[streamName].Item1, GSA.SenderInfo[streamName].Item2, streamName); } } }
private void UpdateStreamWithIds(List <Layer> layers, List <SpeckleObject> bucketObjects, ref int numErrors) { // Update stream with payload var placeholders = new List <SpeckleObject>(); foreach (string id in bucketObjects.Select(bo => bo._id)) { placeholders.Add(new SpecklePlaceholder() { _id = id }); } SpeckleStream updateStream = new SpeckleStream { Layers = layers, Objects = placeholders, Name = StreamName, BaseProperties = GSA.GetBaseProperties() }; try { _ = apiClient.StreamUpdateAsync(StreamID, updateStream).Result; apiClient.Stream.Layers = updateStream.Layers.ToList(); apiClient.Stream.Objects = placeholders; GSA.GsaApp.gsaMessenger.CacheMessage(MessageIntent.Display, MessageLevel.Information, "Updated the stream's object list on the server", StreamID); } catch (Exception ex) { numErrors++; GSA.GsaApp.gsaMessenger.CacheMessage(MessageIntent.Display, MessageLevel.Error, "Updating the stream's object list on the server", StreamID); var speckleExceptionContext = ExtractSpeckleExceptionContext(ex); var errContext = speckleExceptionContext.Concat(new[] { "Error updating the stream's object list on the server", "StreamId=" + StreamID }); GSA.GsaApp.gsaMessenger.CacheMessage(MessageIntent.TechnicalLog, MessageLevel.Error, ex, errContext.ToArray()); } return; }
/// <summary> /// Trigger to update stream. /// </summary> public void Trigger() { if ((IsBusy) || (!IsInit)) { return; } var startTime = DateTime.Now; IsBusy = true; GSA.Settings.Units = GSA.gsaProxy.GetUnits(); //Clear previously-sent objects GSA.ClearSenderDictionaries(); // Read objects var currentBatch = new List <Type>(); bool changeDetected = false; do { ExecuteWithLock(ref traversedSerialisedLock, () => { currentBatch = FilteredReadTypePrereqs.Where(i => i.Value.Count(x => !traversedSerialisedTypes.Contains(x)) == 0).Select(i => i.Key).ToList(); currentBatch.RemoveAll(i => traversedSerialisedTypes.Contains(i)); }); #if DEBUG foreach (var t in currentBatch) { ProcessTypeForSending(t, ref changeDetected); } #else Parallel.ForEach(currentBatch, t => { ProcessTypeForSending(t, ref changeDetected); } ); #endif } while (currentBatch.Count > 0); if (!changeDetected) { Status.ChangeStatus("Finished sending", 100); IsBusy = false; return; } // Separate objects into streams var streamBuckets = CreateStreamBuckets(); TimeSpan duration = DateTime.Now - startTime; Status.AddMessage("Duration of conversion to Speckle: " + duration.ToString(@"hh\:mm\:ss")); startTime = DateTime.Now; // Send package Status.ChangeStatus("Sending to Server"); foreach (var k in streamBuckets.Keys) { Status.ChangeStatus("Sending to stream: " + Senders[k].StreamID); var title = GSA.gsaProxy.GetTitle(); var streamName = GSA.Settings.SeparateStreams ? title + "." + k : title; Senders[k].UpdateName(streamName); Senders[k].SendGSAObjects(streamBuckets[k]); } duration = DateTime.Now - startTime; Status.AddMessage("Duration of sending to Speckle: " + duration.ToString(@"hh\:mm\:ss")); IsBusy = false; Status.ChangeStatus("Finished sending", 100); }
/// <summary> /// Trigger to update stream. /// </summary> public async Task Trigger() { if ((IsBusy) || (!IsInit)) { return; } IsBusy = true; //GSA.App.Settings.Units = GSA.App.Proxy.GetUnits(); #region update_cache var startTime = DateTime.Now; statusProgress.Report("Reading GSA data into cache"); var txTypePrereqs = GSA.TxTypeDependencies; //Update cache var updatedCache = UpdateCache(); if (!updatedCache) { this.loggingProgress.Report(new MessageEventArgs(SpeckleGSAInterfaces.MessageIntent.Display, SpeckleGSAInterfaces.MessageLevel.Error, "Error in communicating GSA - please check if the GSA file has been closed down")); return; } TimeSpan duration = DateTime.Now - startTime; loggingProgress.Report(new MessageEventArgs(SpeckleGSAInterfaces.MessageIntent.Display, SpeckleGSAInterfaces.MessageLevel.Information, "Duration of reading GSA model into cache: " + duration.ToString(@"hh\:mm\:ss"))); loggingProgress.Report(new MessageEventArgs(SpeckleGSAInterfaces.MessageIntent.Telemetry, SpeckleGSAInterfaces.MessageLevel.Information, "send", "update-cache", "duration", duration.ToString(@"hh\:mm\:ss"))); #endregion #region GSA_model_to_SpeckleObjects startTime = DateTime.Now; //Clear previously-sent objects GSA.ClearSenderDictionaries(); lock (traversedSerialisedLock) { traversedSerialisedTypes.Clear(); } var changeDetected = ProcessTxObjects(); if (!changeDetected) { statusProgress.Report("No new or changed objects to send"); IsBusy = false; return; } duration = DateTime.Now - startTime; loggingProgress.Report(new MessageEventArgs(SpeckleGSAInterfaces.MessageIntent.Display, SpeckleGSAInterfaces.MessageLevel.Information, "Duration of conversion to Speckle: " + duration.ToString(@"hh\:mm\:ss"))); loggingProgress.Report(new MessageEventArgs(SpeckleGSAInterfaces.MessageIntent.Telemetry, SpeckleGSAInterfaces.MessageLevel.Information, "send", "conversion", "duration", duration.ToString(@"hh\:mm\:ss"))); #endregion #region create_necessary_streams startTime = DateTime.Now; // Separate objects into streams var allBuckets = CreateStreamBuckets(); var bucketsToCreate = allBuckets.Keys.Except(Senders.Keys).ToList(); //TO DO: review this, possibly move to the kit if (GSA.GsaApp.Settings.StreamSendConfig == StreamContentConfig.TabularResultsOnly && bucketsToCreate.Contains("results")) { bucketsToCreate = new List <string> { "results" }; } //Now check if any streams need to be created if (bucketsToCreate.Count() > 0) { Progress <int> incrementProgress = new Progress <int>(); incrementProgress.ProgressChanged += IncorporateSendPayloadProgress; Progress <int> totalProgress = new Progress <int>(); totalProgress.ProgressChanged += IncorporateNewNumPayloadsProgress; if (savedSenderSidRecords != null && savedSenderSidRecords.Count() > 0) { var sidRecordByBucket = savedSenderSidRecords.ToDictionary(r => r.Bucket, r => r); var savedBuckets = sidRecordByBucket.Keys.ToList(); var reuseBuckets = sidRecordByBucket.Keys.Where(ssn => bucketsToCreate.Any(sn => ssn.Equals(sn, StringComparison.InvariantCultureIgnoreCase))).ToList(); var discardStreamNames = sidRecordByBucket.Keys.Except(reuseBuckets); foreach (var bucket in reuseBuckets) { var sender = gsaSenderCreator(restApi, apiToken); var initialised = await sender.InitializeSender(documentName, sidRecordByBucket[bucket].StreamId, sidRecordByBucket[bucket].ClientId, totalProgress, incrementProgress); if (initialised) { Senders.Add(bucket, sender); bucketsToCreate.Remove(bucket); } } foreach (var dsn in discardStreamNames) { streamDeletionProgress.Report(sidRecordByBucket[dsn]); } } foreach (var sn in bucketsToCreate) { var streamName = string.IsNullOrEmpty(documentTitle) ? "GSA " + sn : documentTitle + " (" + sn + ")"; var sender = gsaSenderCreator(restApi, apiToken); var initialised = await sender.InitializeSender(documentName, streamName, basePropertyUnits, tolerance, angleTolerance, totalProgress, incrementProgress); if (initialised) { Senders.Add(sn, sender); streamCreationProgress.Report(new SidSpeckleRecord(Senders[sn].StreamId, sn, Senders[sn].ClientId, streamName)); } } } #endregion #region send_to_server // Send package statusProgress.Report("Sending to Server"); int numErrors = 0; var sendingTasks = new List <Task>(); foreach (var k in Senders.Keys) { statusProgress.Report("Sending to stream: " + Senders[k].StreamId); numErrors += Senders[k].SendObjects(allBuckets[k]); } if (numErrors > 0) { loggingProgress.Report(new MessageEventArgs(SpeckleGSAInterfaces.MessageIntent.Display, SpeckleGSAInterfaces.MessageLevel.Error, numErrors + " errors found with sending to the server. Refer to the .txt log file(s) in " + AppDomain.CurrentDomain.BaseDirectory)); } duration = DateTime.Now - startTime; loggingProgress.Report(new MessageEventArgs(SpeckleGSAInterfaces.MessageIntent.Display, SpeckleGSAInterfaces.MessageLevel.Information, "Duration of sending to Speckle: " + duration.ToString(@"hh\:mm\:ss"))); loggingProgress.Report(new MessageEventArgs(SpeckleGSAInterfaces.MessageIntent.Telemetry, SpeckleGSAInterfaces.MessageLevel.Information, "send", "sending", "duration", duration.ToString(@"hh\:mm\:ss"))); #endregion IsBusy = false; statusProgress.Report("Finished sending"); }