/// <summary> /// Rearranges the publish request queue. /// </summary> /// <returns><c>True</c> if succesfull, <c>false</c> otherwise.</returns> private bool RearrangePublishRequestQueue() { // Peek on the first PublishRequest in the queue PublishRequest tempRequest; if (!publishRequestQueue.TryPeek(out tempRequest)) { return(false); } string dataModelNamespace = tempRequest.DataModelNamespace; string resourceTypeName = tempRequest.ResourceTypeName; int sameResourceTypeInProgressCount = PublishRequestTracker.Where(request => request.DataModelNamespace.Equals(dataModelNamespace, StringComparison.OrdinalIgnoreCase) && request.ResourceTypeName.Equals(resourceTypeName, StringComparison.OrdinalIgnoreCase) && request.CurrentStatus.CurrentStage != PublishStage.AbortedOnError && request.CurrentStatus.CurrentStage != PublishStage.AbortedOnDemand && request.CurrentStatus.CurrentStage != PublishStage.Completed).Count(); if (sameResourceTypeInProgressCount > 0) { // Rearrange the queue so that all PublishRequests for the same resource type are queued in the back. // This will ensure the same resource type is not processed immediately. Queue <PublishRequest> sameResouceTypeRequestQueue = new Queue <PublishRequest>(); Queue <PublishRequest> otherResouceTypeRequestQueue = new Queue <PublishRequest>(); while (!publishRequestQueue.IsEmpty) { PublishRequest firstRequest; if (!publishRequestQueue.TryDequeue(out firstRequest)) { continue; } if (firstRequest.DataModelNamespace.Equals(dataModelNamespace, StringComparison.OrdinalIgnoreCase) && firstRequest.ResourceTypeName.Equals(resourceTypeName, StringComparison.OrdinalIgnoreCase)) { sameResouceTypeRequestQueue.Enqueue(firstRequest); } else { otherResouceTypeRequestQueue.Enqueue(firstRequest); } } foreach (PublishRequest requestItem in otherResouceTypeRequestQueue) { publishRequestQueue.Enqueue(requestItem); } foreach (PublishRequest requestItem in sameResouceTypeRequestQueue) { publishRequestQueue.Enqueue(requestItem); } PublishRequest.SaveToDatabase(publishRequestQueue, true); return(false); } return(true); }
/// <summary> /// Submits the specified item id. /// </summary> /// <param name="publishRequest">The publish request.</param> public void Submit(PublishRequest publishRequest) { if (publishRequest == null || publishRequest.InstanceId == Guid.Empty) { return; } if (publishRequestQueue.Contains(publishRequest, new PublishRequestComparer())) { return; } publishRequestQueue.Enqueue(publishRequest); publishRequest.SaveToDatabase(true); itemCount++; waitHandle.Set(); }
/// <summary> /// Processes the publish request. /// </summary> /// <param name="currentPublishRequest">The current publish request.</param> private void ProcessPublishRequest(PublishRequest currentPublishRequest) { Globals.TraceMessage(TraceEventType.Information, currentPublishRequest.ToString(), string.Format(Properties.Messages.StartedProcessingQueuedPublishRequest, currentPublishRequest.InstanceId)); // Add the item in the Request Tracker // Remove old requests of the same resourcetype from the Request Tracker lock (PublishRequestTracker) { PublishRequestTracker.RemoveWhere(request => request.DataModelNamespace.Equals(currentPublishRequest.DataModelNamespace, StringComparison.OrdinalIgnoreCase) && request.ResourceTypeName.Equals(currentPublishRequest.ResourceTypeName, StringComparison.OrdinalIgnoreCase)); PublishRequestTracker.Add(currentPublishRequest); currentPublishRequest.DeleteFromDatabase(false, true); currentPublishRequest.SaveToDatabase(false); } // If the request is a cancelled request then mark it as AbortedOnDemand and save to database. if (currentPublishRequest.IsCancellationRequested) { currentPublishRequest.CurrentStatus.CurrentStage = PublishStage.AbortedOnDemand; currentPublishRequest.SaveToDatabase(false); return; } try { using (Process zentityCollectionCreator = new Process()) { zentityCollectionCreator.StartInfo = new ProcessStartInfo() { // Create the Zentity.Pivot.CollectionCreator Process FileName = Path.Combine(Utilities.AssemblyLocation, "Zentity.Pivot.CollectionCreator.exe"), // Pass the specific arguments to the process Arguments = string.Format("/operation:{0} /instanceId:{1} /modelNamespace:{2} /resourceType:{3} {4}", currentPublishRequest.Operation, currentPublishRequest.InstanceId, currentPublishRequest.DataModelNamespace, currentPublishRequest.ResourceTypeName, currentPublishRequest.Operation == PublishOperation.UpdateCollection ? string.Format("/changemessagefilepath:\"{0}\"", currentPublishRequest.ChangeMessageFilePath) : string.Empty), UseShellExecute = false, RedirectStandardOutput = true }; currentPublishRequest.CurrentStatus.CurrentStage = PublishStage.Initiating; zentityCollectionCreator.Start(); // Read the output stream first and then wait. string output = zentityCollectionCreator.StandardOutput.ReadToEnd(); // Thread waits till the process exits zentityCollectionCreator.WaitForExit(); // Analyze the ExitCode and throw the correct execption. switch (zentityCollectionCreator.ExitCode) { // CollectionCreator has exited with a ReturnCode case (int)ReturnCode.Error: case (int)ReturnCode.Invalid: throw new ApplicationException(output.Replace("\n", "\r\n")); // User has ended the CollectionCreator process from Task Manager etc. case 1: throw new InvalidOperationException(Properties.Messages.CollectionCreatorProcessKilled); } } } catch (Exception ex) { Globals.TraceMessage(TraceEventType.Error, ex.ToString(), string.Format(Properties.Messages.ExceptionProcessingPublishRequest, currentPublishRequest.InstanceId)); currentPublishRequest.CurrentStatus.CurrentStage = PublishStage.AbortedOnError; currentPublishRequest.PublishingCallback = null; } // Do cleanup, if the CollectionCreator process has not done itself. try { string directoryPath = Path.Combine(Path.GetTempPath(), currentPublishRequest.InstanceId.ToString()); string imagesPath = Path.Combine(Path.GetTempPath(), string.Format("{0}_Images", currentPublishRequest.InstanceId)); if (Directory.Exists(directoryPath)) { Directory.Delete(directoryPath, true); } if (Directory.Exists(imagesPath)) { Directory.Delete(imagesPath, true); } } catch { } // If the Collection creator has not been able to report progress (highly unlikely). // Assume that the operation completed successfully. if (currentPublishRequest.CurrentStatus.CurrentStage == PublishStage.NotStarted || currentPublishRequest.CurrentStatus.CurrentStage == PublishStage.Initiating) { Globals.TraceMessage(TraceEventType.Information, string.Empty, string.Format(Properties.Messages.CollectionCreatorProgressReportFailure, currentPublishRequest.InstanceId)); currentPublishRequest.CurrentStatus.CurrentStage = PublishStage.Completed; } currentPublishRequest.SaveToDatabase(false); lock (lockObject) { processedItemCount++; Monitor.Pulse(lockObject); } Globals.TraceMessage(TraceEventType.Information, currentPublishRequest.ToString(), string.Format(Properties.Messages.FinishedProcessingQueuedPublishRequest, currentPublishRequest.InstanceId)); }