Пример #1
0
        private void Controller()
        {
            while (true)
            {
                PublishHelper.LogVerboseInformation("ControllerThread: Waiting for operations");
                int eventId = WaitHandle.WaitAny(_waitHandleArray, Interval);
                if (eventId == 0)
                {
                    //If exitevent is signalled, the process is exiting.
                    break;
                }

                if (!PublishHelper.ShouldBeginProcessingPublishOperation)
                {
                    PublishHelper.LogVerboseInformation("ControllerThread: BeginProcessing is currently off");
                    _continueEvent.Reset();
                    continue;
                }

                int maxConcurrentOperations = PublishHelper.MaxConcurrentSyncOperations;

                ThreadPool.SetMaxThreads(maxConcurrentOperations, maxConcurrentOperations);

                if (!_operationInitialized)
                {
                    _operationInitialized = true;
                    PublishHelper.LogVerboseInformation("ControllerThread: Initializing publish operation");
                }

                #region Schedule Operations

                _continueEvent.Reset();
                PublishOperation publishOperation;
                try
                {
                    while (PublishHelper.GetNextPublishOperation(out publishOperation))
                    {
                        if (_exitEvent.WaitOne(0))
                        {
                            //If this is signalled, the process is exiting
                            return;
                        }

                        string physicalPath = string.Empty;
                        bool   siteInvalid  = false;
                        try
                        {
                            // if the site was added or updated and then deleted, the add and update
                            // operations get always scheduled before the delete.
                            // so if the site is deleted, this will throw object not found exception.
                            // set the object as invalid so that this is never attempted again.
                            physicalPath = publishOperation.PhysicalPath;
                        }
                        catch (WebHostingObjectNotFoundException)
                        {
                            siteInvalid = true;
                        }

                        WaitCallback callback  = null;
                        Operation    operation = new Operation(
                            publishOperation.OperationId,
                            publishOperation.SiteName,
                            physicalPath,
                            PublishHelper.PublishUrl,
                            PublishHelper.AdminCredential);
                        int currentOperationCount = 0;

                        if (siteInvalid)
                        {
                            operation.Status = PublishOperationStatus.SourceOrDestinationInvalid;
                            lock (_completedOperations)
                            {
                                PublishHelper.LogVerboseInformation("ControllerThread: Queuing completed operation for site: {0} as it does not exist", operation.SiteName);
                                _completedOperations.Enqueue(operation);
                            }
                            continue;
                        }

                        PublishHelper.LogVerboseInformation("ControllerThread: Adding Operation {0} for {1} to the queue", operation.SiteName, publishOperation.SiteState);
                        if (publishOperation.SiteState == SiteState.Deleted)
                        {
                            lock (_pendingDeleteOperations)
                            {
                                _pendingDeleteOperations.Enqueue(operation);
                                currentOperationCount += _pendingDeleteOperations.Count;
                            }

                            callback = new WaitCallback(DeleteContent);
                        }
                        else
                        {
                            lock (_pendingPublishOperations)
                            {
                                _pendingPublishOperations.Enqueue(operation);
                                currentOperationCount += _pendingPublishOperations.Count;
                            }

                            callback = new WaitCallback(Publish);
                        }

                        AntaresEventProvider.EventWritePublishFailOverServiceOperationQueued(operation.SiteName);
                        ThreadPool.QueueUserWorkItem(callback);
                        AntaresEventProvider.EventWritePublishFailOverServiceDebugEvent(String.Format("ControllerThread: Current in queue: {0}, maxCount: {1}", currentOperationCount, maxConcurrentOperations));
                        if (currentOperationCount >= maxConcurrentOperations)
                        {
                            /// Dont queue more operations than the max count to let other publishers pick these operations up.
                            /// This does not mean that we will wait for the entire interval. As soon as a thread finishes, the continue event will
                            /// get signalled and new operations will get picked up till maxcount operations are queued again.
                            break;
                        }
                    }
                }
                catch (Exception ex)
                {
                    AntaresEventProvider.EventWritePublishFailOverServiceUnableToGetNextOperation(ex.ToString());
                }

                #endregion
            }
        }