public static void Tickle(Guid mailboxGuid, Guid requestQueueMdbGuid, MoveRequestNotification operation) { MrsTracer.Service.Debug("Processing tickled mailbox: {0}, requestQueueMdbGuid: {1}, operation: {2}", new object[] { mailboxGuid, requestQueueMdbGuid, operation }); if (MailboxSyncerJobs.ProcessJob(mailboxGuid, false, delegate(BaseJob job) { job.NeedToRefreshRequest = true; })) { return; } MRSQueue mrsqueue = MRSQueue.Get(requestQueueMdbGuid); switch (operation) { case MoveRequestNotification.Created: case MoveRequestNotification.Canceled: mrsqueue.Tickle(MRSQueue.ScanType.Heavy); return; case MoveRequestNotification.Updated: case MoveRequestNotification.SuspendResume: mrsqueue.Tickle(MRSQueue.ScanType.Light); mrsqueue.Tickle(MRSQueue.ScanType.Heavy); return; default: return; } }
public static void CreateJob(TransactionalRequestJob requestJob, ReservationContext reservation) { BaseJob baseJob; lock (MailboxSyncerJobs.syncRoot) { Guid guid = (requestJob.RequestType == MRSRequestType.Move) ? requestJob.ExchangeGuid : requestJob.RequestGuid; baseJob = MailboxSyncerJobs.FindJob(guid, false); if (baseJob != null) { MrsTracer.Service.Error("Request {0} is already being worked on.", new object[] { guid }); return; } baseJob = MailboxSyncerJobs.ConstructJob(requestJob); if (baseJob == null) { MrsTracer.Service.Error("Don't know how to process '{0}' request", new object[] { requestJob.RequestType }); return; } baseJob.Initialize(requestJob); baseJob.Reservation = reservation; MailboxSyncerJobs.activeJobs.Add(guid, baseJob); MailboxSyncerJobs.activeJobsIsEmpty.Reset(); } JobScheduler.ScheduleJob(baseJob); }
protected override void InternalDispose(bool calledFromDispose) { if (calledFromDispose) { MailboxSyncerJobs.StopScheduling(); } }
public static void StartScheduling() { SystemWorkloadManager.Initialize(MrsAndProxyActivityLogger.Start()); MailboxSyncerJobs.GetScheduler(WorkloadType.MailboxReplicationServiceHighPriority); MailboxSyncerJobs.GetScheduler(WorkloadType.MailboxReplicationServiceInteractive); MailboxSyncerJobs.GetScheduler(WorkloadType.MailboxReplicationServiceInternalMaintenance); MailboxSyncerJobs.GetScheduler(WorkloadType.MailboxReplicationService); }
public void StartService() { MRSService.scheduledLogsList.Add(new MRSSettingsLog()); MailboxSyncerJobs.StartScheduling(); MRSService.jobPoller.Start(); MRSService.lightJobPoller.Start(); MRSService.issueCache.EnableScanning(); MRSService.logDumper.Start(); ProcessAccessManager.RegisterComponent(this); ProcessAccessManager.RegisterComponent(MRSService.issueCache); ProcessAccessManager.RegisterComponent(ConfigBase <MRSConfigSchema> .Provider); }
public void StopService() { MrsTracer.Service.Debug("Stopping service...", new object[0]); CommonUtils.ServiceIsStopping = true; MRSService.lightJobPoller.WaitForJobToBeDone(); MRSService.jobPoller.WaitForJobToBeDone(); MailboxSyncerJobs.WaitForAllJobsToComplete(); ProcessAccessManager.UnregisterComponent(ConfigBase <MRSConfigSchema> .Provider); ProcessAccessManager.UnregisterComponent(MRSService.issueCache); ProcessAccessManager.UnregisterComponent(this); MailboxSyncerJobs.StopScheduling(); MRSService.LogEvent(MRSEventLogConstants.Tuple_ServiceStopped, new object[0]); MrsTracer.Service.Debug("Service stopped.", new object[0]); }
MoveRequestInfo IMailboxReplicationService.GetMoveRequestInfo(Guid requestGuid) { MoveRequestInfo result = new MoveRequestInfo(); this.ForwardKnownExceptions(delegate { if (!MailboxSyncerJobs.ProcessJob(requestGuid, false, delegate(BaseJob job) { result = job.GetMoveRequestInfo(); })) { MrsTracer.Service.Debug("Request {0} is not active.", new object[] { requestGuid }); result.Message = MRSQueue.GetJobPickupFailureMessageForRequest(requestGuid); } }, null); return(result); }
string IMailboxReplicationService.ValidateAndPopulateRequestJob(string requestJobXML, out string reportEntryXMLs) { string reportString = null; string resultString = null; try { this.ForwardKnownExceptions(delegate { List <ReportEntry> list = new List <ReportEntry>(); try { RequestJobXML requestJob = XMLSerializableBase.Deserialize <RequestJobXML>(requestJobXML, true); using (TransactionalRequestJob transactionalRequestJob = new TransactionalRequestJob(requestJob)) { transactionalRequestJob.IsFake = true; transactionalRequestJob.Identity = new RequestJobObjectId((transactionalRequestJob.RequestType == MRSRequestType.Move) ? transactionalRequestJob.ExchangeGuid : transactionalRequestJob.RequestGuid, (transactionalRequestJob.WorkItemQueueMdb == null) ? Guid.Empty : transactionalRequestJob.WorkItemQueueMdb.ObjectGuid, null); RequestIndexEntryProvider requestIndexEntryProvider = new RequestIndexEntryProvider(); using (requestIndexEntryProvider.RescopeTo(transactionalRequestJob.DomainControllerToUpdate, transactionalRequestJob.OrganizationId)) { if (transactionalRequestJob.SourceUserId != null) { transactionalRequestJob.SourceUser = requestIndexEntryProvider.ReadADUser(transactionalRequestJob.SourceUserId, transactionalRequestJob.SourceExchangeGuid); } if (transactionalRequestJob.TargetUserId != null) { transactionalRequestJob.TargetUser = requestIndexEntryProvider.ReadADUser(transactionalRequestJob.TargetUserId, transactionalRequestJob.TargetExchangeGuid); } } if (MailboxSyncerJobs.ContainsJob(transactionalRequestJob.IdentifyingGuid)) { resultString = requestJobXML; } else { BaseJob baseJob = MailboxSyncerJobs.ConstructJob(transactionalRequestJob); if (baseJob == null) { MrsTracer.Service.Error("Don't know how to process '{0}' request", new object[] { transactionalRequestJob.RequestType }); throw new RequestTypeNotUnderstoodPermanentException(CommonUtils.LocalComputerName, VersionInformation.MRS.ToString(), (int)transactionalRequestJob.RequestType); } using (baseJob) { baseJob.Initialize(transactionalRequestJob); baseJob.ValidateAndPopulateRequestJob(list); transactionalRequestJob.Message = baseJob.CachedRequestJob.Message; transactionalRequestJob.SourceVersion = baseJob.CachedRequestJob.SourceVersion; transactionalRequestJob.SourceArchiveVersion = baseJob.CachedRequestJob.SourceArchiveVersion; transactionalRequestJob.SourceServer = baseJob.CachedRequestJob.SourceServer; transactionalRequestJob.SourceArchiveServer = baseJob.CachedRequestJob.SourceArchiveServer; transactionalRequestJob.TargetVersion = baseJob.CachedRequestJob.TargetVersion; transactionalRequestJob.TargetArchiveVersion = baseJob.CachedRequestJob.TargetArchiveVersion; transactionalRequestJob.TargetServer = baseJob.CachedRequestJob.TargetServer; transactionalRequestJob.TargetArchiveServer = baseJob.CachedRequestJob.TargetArchiveServer; transactionalRequestJob.RemoteDatabaseGuid = baseJob.CachedRequestJob.RemoteDatabaseGuid; resultString = XMLSerializableBase.Serialize(new RequestJobXML(transactionalRequestJob), false); } } } } finally { reportString = XMLSerializableBase.Serialize(list, false); } }, null); } finally { reportEntryXMLs = reportString; } return(resultString); }
public JobPickupRec AttemptToPick(MapiStore systemMailbox) { if (!RequestJobXML.IsKnownRequestType(this.RequestType)) { return(new JobPickupRec(this, JobPickupResult.UnknownJobType, DateTime.MaxValue, MrsStrings.PickupStatusRequestTypeNotSupported(this.RequestType.ToString()), null)); } if (!RequestJobXML.IsKnownJobType(this.JobType)) { return(new JobPickupRec(this, JobPickupResult.UnknownJobType, DateTime.MaxValue, MrsStrings.PickupStatusJobTypeNotSupported(this.JobType.ToString()), null)); } if (this.PoisonCount >= ConfigBase <MRSConfigSchema> .GetConfig <int>("HardPoisonLimit")) { return(new JobPickupRec(this, JobPickupResult.PoisonedJob, DateTime.MaxValue, MrsStrings.PickupStatusJobPoisoned(this.PoisonCount), null)); } if (this.IsActiveOnThisMRSInstance) { return(new JobPickupRec(this, JobPickupResult.JobAlreadyActive, DateTime.MaxValue, LocalizedString.Empty, null)); } DateTime utcNow = DateTime.UtcNow; if (this.Status == RequestStatus.Completed && (!this.DoNotPickUntilHasElapsed || this.DoNotPickUntilTimestamp == DateTime.MinValue) && !this.RehomeRequest) { return(new JobPickupRec(this, JobPickupResult.CompletedJobSkipped, (this.DoNotPickUntilTimestamp == DateTime.MinValue) ? DateTime.MaxValue : this.DoNotPickUntilTimestamp, LocalizedString.Empty, null)); } if (this.CancelRequest && !this.DoNotPickUntilHasElapsed) { return(new JobPickupRec(this, JobPickupResult.PostponeCancel, this.DoNotPickUntilTimestamp, LocalizedString.Empty, null)); } if (!this.isInteractive && !this.IsLightRequest && !this.DoNotPickUntilHasElapsed) { MrsTracer.Service.Debug("Ignoring MoveJob '{0}' on queue '{1}' having DoNotPickUntilTimestamp of {2}.", new object[] { this.RequestGuid, this.RequestQueueGuid, this.DoNotPickUntilTimestamp.ToLocalTime() }); return(new JobPickupRec(this, JobPickupResult.JobIsPostponed, this.DoNotPickUntilTimestamp, LocalizedString.Empty, null)); } if (this.InternalFlags.HasFlag(RequestJobInternalFlags.ExecutedByTransportSync)) { MrsTracer.Service.Debug("Ignoring MoveJob '{0}' since Tranport Sync Owns Execution of the job.", new object[] { this.RequestGuid }); return(new JobPickupRec(this, JobPickupResult.JobOwnedByTransportSync, DateTime.MaxValue, LocalizedString.Empty, null)); } JobPickupRec result; using (DisposeGuard disposeGuard = default(DisposeGuard)) { using (RequestJobProvider requestJobProvider = new RequestJobProvider(this.RequestQueueGuid, systemMailbox)) { using (TransactionalRequestJob transactionalRequestJob = (TransactionalRequestJob)requestJobProvider.Read <TransactionalRequestJob>(new RequestJobObjectId(this.RequestGuid, this.RequestQueueGuid, this.MessageID))) { if (transactionalRequestJob == null) { result = new JobPickupRec(this, JobPickupResult.InvalidJob, DateTime.MaxValue, MrsStrings.PickupStatusCorruptJob, null); } else if (!transactionalRequestJob.IsSupported()) { result = new JobPickupRec(this, JobPickupResult.UnknownJobType, DateTime.MaxValue, MrsStrings.PickupStatusSubTypeNotSupported(transactionalRequestJob.RequestType.ToString()), null); } else if (transactionalRequestJob.ValidationResult != RequestJobBase.ValidationResultEnum.Valid) { this.ProcessInvalidJob(transactionalRequestJob, requestJobProvider); result = new JobPickupRec(this, JobPickupResult.InvalidJob, DateTime.MaxValue, MrsStrings.PickupStatusInvalidJob(transactionalRequestJob.ValidationResult.ToString(), transactionalRequestJob.ValidationMessage), null); } else if (transactionalRequestJob.Status == RequestStatus.Completed && !transactionalRequestJob.RehomeRequest) { this.CleanupCompletedJob(transactionalRequestJob, requestJobProvider); result = new JobPickupRec(this, JobPickupResult.CompletedJobCleanedUp, DateTime.MaxValue, MrsStrings.PickupStatusCompletedJob, null); } else if (!transactionalRequestJob.ShouldProcessJob()) { result = new JobPickupRec(this, JobPickupResult.DisabledJobPickup, DateTime.MaxValue, MrsStrings.PickupStatusDisabled, null); } else { ReservationContext reservationContext = null; if (!this.IsLightRequest && !MoveJob.CacheJobQueues) { reservationContext = new ReservationContext(); disposeGuard.Add <ReservationContext>(reservationContext); try { this.ReserveLocalForestResources(reservationContext, transactionalRequestJob); } catch (LocalizedException ex) { if (CommonUtils.ExceptionIs(ex, new WellKnownException[] { WellKnownException.ResourceReservation })) { return(new JobPickupRec(this, JobPickupResult.ReservationFailure, utcNow + MoveJob.JobPickupRetryInterval, MrsStrings.PickupStatusReservationFailure(CommonUtils.FullExceptionMessage(ex)), ex as ResourceReservationException)); } throw; } } if (!TestIntegration.Instance.DisableRemoteHostNameBlacklisting && transactionalRequestJob.RequestType == MRSRequestType.Move && (transactionalRequestJob.Flags & RequestFlags.CrossOrg) != RequestFlags.None && (transactionalRequestJob.Flags & RequestFlags.RemoteLegacy) == RequestFlags.None && !string.IsNullOrEmpty(transactionalRequestJob.RemoteHostName)) { string key = transactionalRequestJob.RemoteHostName.ToLowerInvariant(); DateTime nextRecommendedPickup; if (MoveJob.RemoteHostsInProxyBackoff.TryGetValue(key, out nextRecommendedPickup)) { return(new JobPickupRec(this, JobPickupResult.ProxyBackoff, nextRecommendedPickup, MrsStrings.PickupStatusProxyBackoff(transactionalRequestJob.RemoteHostName), null)); } } MrsTracer.Service.Debug("Attempting to take over MoveJob '{0}' on queue '{1}', priority={2}", new object[] { transactionalRequestJob, this.RequestQueueGuid, transactionalRequestJob.Priority }); transactionalRequestJob.RequestJobState = JobProcessingState.InProgress; transactionalRequestJob.MRSServerName = CommonUtils.LocalComputerName; if (!this.IsLightRequest) { transactionalRequestJob.PoisonCount++; transactionalRequestJob.LastPickupTime = new DateTime?(DateTime.UtcNow); } if (!transactionalRequestJob.Suspend && !transactionalRequestJob.RehomeRequest && transactionalRequestJob.Status != RequestStatus.Suspended && transactionalRequestJob.Status != RequestStatus.AutoSuspended && transactionalRequestJob.Status != RequestStatus.Failed && transactionalRequestJob.Status != RequestStatus.Completed && transactionalRequestJob.Status != RequestStatus.CompletedWithWarning) { transactionalRequestJob.Status = ((reservationContext == null) ? RequestStatus.Queued : RequestStatus.InProgress); } requestJobProvider.Save(transactionalRequestJob); this.Status = transactionalRequestJob.Status; JobPickupRec jobPickupRec; if (this.IsLightRequest) { jobPickupRec = new JobPickupRec(this, JobPickupResult.JobPickedUp, DateTime.MaxValue, MrsStrings.PickupStatusLightJob(transactionalRequestJob.Suspend, transactionalRequestJob.RehomeRequest, transactionalRequestJob.Priority.ToString()), null); MoveJob.PerformLightJobAction(requestJobProvider.SystemMailbox, RequestJobProvider.CreateRequestStatistics(transactionalRequestJob)); } else { MailboxSyncerJobs.CreateJob(transactionalRequestJob, reservationContext); jobPickupRec = new JobPickupRec(this, JobPickupResult.JobPickedUp, DateTime.MaxValue, MrsStrings.PickupStatusCreateJob(transactionalRequestJob.SyncStage.ToString(), transactionalRequestJob.CancelRequest, transactionalRequestJob.Priority.ToString()), null); } disposeGuard.Success(); result = jobPickupRec; } } } } return(result); }
public static bool JobIsActive(Guid mailboxGuid) { CommonUtils.CheckForServiceStopping(); return(MailboxSyncerJobs.FindJob(mailboxGuid, false) != null); }
XElement IDiagnosable.GetDiagnosticInfo(DiagnosableParameters parameters) { XElement xelement = new XElement(MRSService.DiagnosticsComponentName); MRSDiagnosticArgument arguments; try { arguments = new MRSDiagnosticArgument(parameters.Argument); } catch (DiagnosticArgumentException ex) { xelement.Add(new XElement("Error", "Encountered exception: " + ex.Message)); return(xelement); } xelement.Add(new object[] { new XElement("ServiceStartTime", MRSService.serviceStartTime), new XElement("LastScanDuration", MRSService.lastFullScanDuration), new XElement("LastScanTime", MRSService.lastFullScanTime.ToString()), new XElement("DurationSinceLastScan", (long)(DateTime.UtcNow - MRSService.lastFullScanTime).TotalMilliseconds), new XElement("NextFullScanTime", MRSService.NextFullScanTime.ToString()), new XElement("NextLightJobsFullScanTime", MRSService.nextLightJobsFullScanTime.ToString()) }); if (arguments.ArgumentCount == 0) { xelement.Add(new XElement("Help", "Supported arguments: " + arguments.GetSupportedArguments())); } if (arguments.HasArgument("binaryversions")) { string assemblyNamePattern = arguments.GetArgument <string>("binaryversions"); xelement.Add(arguments.RunDiagnosticOperation(() => CommonUtils.GetBinaryVersions(assemblyNamePattern))); } if (arguments.HasArgument("job")) { xelement.Add(arguments.RunDiagnosticOperation(() => MailboxSyncerJobs.GetJobsDiagnosticInfo(arguments))); } if (arguments.HasArgument("reservations")) { xelement.Add(arguments.RunDiagnosticOperation(() => ReservationManager.GetReservationsDiagnosticInfo(arguments))); } if (arguments.HasArgument("resources")) { xelement.Add(arguments.RunDiagnosticOperation(() => ReservationManager.GetResourcesDiagnosticInfo(arguments))); } if (arguments.HasArgument("queues")) { xelement.Add(arguments.RunDiagnosticOperation(() => MRSQueue.GetDiagnosticInfo(arguments))); } if (arguments.HasArgument("workloads")) { XElement xelement2 = new XElement("Workloads"); foreach (object obj in Enum.GetValues(typeof(RequestWorkloadType))) { RequestWorkloadType requestWorkloadType = (RequestWorkloadType)obj; if (requestWorkloadType != RequestWorkloadType.None) { GenericSettingsContext genericSettingsContext = new GenericSettingsContext("RequestWorkloadType", requestWorkloadType.ToString(), null); using (genericSettingsContext.Activate()) { bool config = ConfigBase <MRSConfigSchema> .GetConfig <bool>("IsJobPickupEnabled"); xelement2.Add(new XElement("Workload", new object[] { new XAttribute("Name", requestWorkloadType.ToString()), new XAttribute("IsJobPickupEnabled", config) })); } } } xelement.Add(xelement2); } return(xelement); }