private bool DeleteInstanceInternal(IComparable instanceId, bool replicate, long evictionVersion) { Requires.Argument("instanceId", instanceId).NotNull(); StatefulServiceExecutionContext executionContext = StatefulServiceExecutionContext.Current as StatefulServiceExecutionContext; if (executionContext == null || executionContext.Partition == null) { throw new InvalidOperationException("Program instance cannot be obtained outside context of a partition. Please ensure that StatefulServiceReplicaT.Invoke is called."); } StatefulProgramInstance instance = null; ItemCollection <IComparable, StatefulProgramInstance> instances; using (this.instanceManager.GetInstances(LockPermission.Write, out instances)) { if (instances.Contains(instanceId)) { instance = (StatefulProgramInstance)instances[instanceId]; if (evictionVersion != -2 && !instance.CanEvict(evictionVersion)) { return(false); } instances.Remove(instanceId); ((IDisposable)instance).Dispose(); } } if (instance != null) { if (replicate) { Replicable <StatefulProgramInstance> replicable = new Replicable <StatefulProgramInstance>(instance.Id.ToString(), instance); ReplicationScope replicationScope = new ReplicationScope(new Replicable[] { replicable }, ReplicationOperationType.Evict); replicationScope.ReplicateAsync().ContinueWith( task => { ReplicationResult result = task.IsFaulted ? ReplicationResult.Failed : task.Result; if (result != ReplicationResult.Success) { AppTrace.TraceMsg(TraceLogEventType.Warning, "StatefulServiceReplicaT.DeleteInstanceInternal", "Replication call to dispose the instance with id {0} failed.", instance.Id); } }, TaskContinuationOptions.ExecuteSynchronously); } return(true); } else { return(false); } }
public void Notify() { ReplicationResult result = new ReplicationResult(); result.OperatorNodeID = NotifyingNode; result.Description = null; result.LastNodeID = null; result.LastUSN = 0; result.LastChange = DateTime.Now.Ticks; result.ReplicationStatus = ReplicationStatus.Notify; result.Save(); }
protected override bool Run(object parameters) { #if DEBUG Shared.EventLog.Debug("RepThread " + System.Reflection.MethodBase.GetCurrentMethod().Name); #endif DatabaseConnection connection = (DatabaseConnection)parameters; bool tableUpdated = false; TimeSpan ts = new TimeSpan(0, 2, 0); if (!_IsRunning && (DateTime.Now - _lastCheckUpdates) >= ts) { try { _lastCheckUpdates = DateTime.Now; // are we looking for remote updates to the database if (connection.RemoteUpdate) { AddToLogFile(String.Format("{0} Checking Version", ConnectionName)); API api = new API(); try { DatabaseRemoteUpdate remoteUpdate = new DatabaseRemoteUpdate(); try { remoteUpdate.OnNewMessage += DatabaseRemoteUpdate_OnNewMessage; int version = Version; if (remoteUpdate.CheckForDatabaseUpdates(connection.Name, connection.ChildDatabase, connection.RemoteUpdateXML, connection.RemoteUpdateLocation, ref version, ref tableUpdated)) { Version = version; if (api.UpdateCurrentDatabaseVersion(connection, version)) { string fileName = String.Empty; if (connection.ReplicateDatabase && connection.ReplicateUpdateTriggers && tableUpdated) { if (connection.ReplicationType == ReplicationType.Child) { //create replication triggers if needed and new database users ReplicationPrepareChildDatabase repEng = new ReplicationPrepareChildDatabase(); try { if (tableUpdated) { AddToLogFile(String.Format("{0} Rebuilding Child Replication Triggers", ConnectionName)); } if (repEng.PrepareDatabaseForReplication(_databaseConnection.ChildDatabase, tableUpdated, false, ref fileName, remoteUpdate)) { AddToLogFile(String.Format("{0} Replication Child Triggers Rebuilt", ConnectionName)); } } finally { repEng = null; } } else if (connection.ReplicationType == ReplicationType.Master) { //create replication triggers if needed and new database users ReplicationPrepareMasterDatabase repEng = new ReplicationPrepareMasterDatabase(); try { if (tableUpdated) { AddToLogFile(String.Format("{0} Rebuilding Master Replication Triggers", ConnectionName)); } if (repEng.PrepareDatabaseForReplication(_databaseConnection.ChildDatabase, tableUpdated, false, ref fileName, remoteUpdate)) { AddToLogFile(String.Format("{0} Replication Master Triggers Rebuilt", ConnectionName)); } } finally { repEng = null; } } } } } } finally { remoteUpdate.OnNewMessage -= DatabaseRemoteUpdate_OnNewMessage; remoteUpdate = null; } } finally { api = null; } } // are we backing up the database if (connection.BackupDatabase) { DateTime compare = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, connection.BackupAfterTime.Hour, connection.BackupAfterTime.Minute, 0); TimeSpan spanLastBackup = DateTime.Now - connection.LastBackupTime; if ( ( (!connection.BackupAfterTimeEnabled || (connection.BackupAfterTimeEnabled && DateTime.Now.Subtract(compare).TotalMinutes >= 0) ) || (spanLastBackup.TotalDays >= 1.0) )) { AddToLogFile(String.Format("{0} Checking Backup", ConnectionName)); CheckLatestDBBackup(); } else { } } } catch (Exception errUB) { Shared.EventLog.Add(errUB); } } int missingRecordCount = 0; try { if (CanReplicate && connection.ReplicationType == ReplicationType.Child) { ts = new TimeSpan(0, _runInterval, 0); // xx minute increments // has it been xx minutes since last run? if (!_IsRunning && (DateTime.Now - LastRunReplication) >= ts) { AddToLogFile(String.Format("Run Replication {0}", ConnectionName)); _IsRunning = true; //properties _replicationEngine = new ReplicationEngine( ConnectionName, _databaseConnection.ReplicateDatabase, _databaseConnection.ChildDatabase, _databaseConnection.MasterDatabase); try { _replicationEngine.Validate = true; // settings _replicationEngine.VerifyAllDataInterval = (int)_databaseConnection.VerifyDataInterval; _replicationEngine.VerifyTableCounts = 20; #if ERROR_LIMIT_30000 _replicationEngine.ForceRestartErrorCount = 30000; #else _replicationEngine.ForceRestartErrorCount = (int)_databaseConnection.VerifyErrorReset; #endif _replicationEngine.MaximumDownloadCount = (int)_databaseConnection.MaximumDownloadCount; _replicationEngine.MaximumUploadCount = (int)_databaseConnection.MaximumUploadCount; _replicationEngine.TimeOutMinutes = (int)_databaseConnection.TimeOut; _replicationEngine.RequireUniqueAccess = _databaseConnection.RequireUniqueAccess; // event hookups _replicationEngine.OnProgress += new ReplicationPercentEventArgs(rep_OnProgress); _replicationEngine.OnReplicationTextChanged += new ReplicationProgress(rep_OnReplicationTextChanged); _replicationEngine.BeginReplication += new ReplicationEventHandler(rep_BeginReplication); _replicationEngine.EndReplication += new ReplicationEventHandler(rep_EndReplication); _replicationEngine.OnReplicationError += new ReplicationError(rep_OnReplicationError); _replicationEngine.OnIDChanged += rep_OnIDChanged; _replicationEngine.OnCheckCancel += _replicationEngine_OnCheckCancel; //are we forcing hard confirm between certain hours? if (!ForceVerifyRecords) { ForceVerifyRecords = ForceConfirmBasedOnHoursOrIterations(); } _replicationError = _replicationEngine.Run(_allowConfirmCounts, ForceVerifyRecords); missingRecordCount = _replicationEngine.MissingRecordCount; switch (_replicationError) { case ReplicationResult.ThresholdExceeded: _runInterval = 0; break; case ReplicationResult.UniqueAccessDenied: // we do not reset force hard confirm here as it was set before the run //_forceHardConfirm = _forceHardConfirm; _runInterval = (int)_databaseConnection.ReplicateInterval; break; } if (ForceVerifyRecords && (missingRecordCount >= _databaseConnection.VerifyErrorReset)) { AddToLogFile(String.Format("{0} Force Verify Records Missing Records Exceeded", ConnectionName)); ForceVerifyRecords = true; _runInterval = 0; // get list of confirmed tables so we don't scan them next time //_confirmedTables = _replicationEngine.TablesConfirmedCorrect; } else { switch (_replicationError) { case ReplicationResult.TimeOutExceeded: //_confirmedTables = _replicationEngine.TablesConfirmedCorrect; _runInterval = (int)_databaseConnection.ReplicateInterval; AddToLogFile(String.Format("{0} Time out exceeded, restarting", ConnectionName)); break; case ReplicationResult.ThresholdExceeded: //_confirmedTables = _replicationEngine.TablesConfirmedCorrect; // we do not reset force hard confirm here as it was set before the run //_forceHardConfirm = _forceHardConfirm; _runInterval = 0; break; case ReplicationResult.UniqueAccessDenied: //_confirmedTables = _replicationEngine.TablesConfirmedCorrect; _runInterval = (int)_databaseConnection.ReplicateInterval; AddToLogFile(String.Format("{0} Unique access for deep scan not allowed, retry next time...", ConnectionName)); break; case ReplicationResult.Error: case ReplicationResult.DeepScanInitialised: //_confirmedTables = _replicationEngine.TablesConfirmedCorrect; _runInterval = 0; break; case ReplicationResult.NotInitialised: case ReplicationResult.Cancelled: case ReplicationResult.Completed: case ReplicationResult.DeepScanCompleted: ForceVerifyRecords = false; //_confirmedTables = String.Empty; _replicationEngine.Statuses.Clear(); _runInterval = (int)_databaseConnection.ReplicateInterval; break; } } } finally { _replicationEngine.Dispose(); _replicationEngine = null; } _IsRunning = false; LastRunReplication = DateTime.Now; _replicationCount++; //log management Shared.EventLog.ArchiveOldLogFiles(); } } TimeSpan t = LastRunReplication.AddMinutes(_runInterval) - DateTime.Now; SendToTCPClients(String.Format("Sleeping, time until next run {0}", t.ToString().Substring(0, 8))); } catch (Exception err) { Shared.EventLog.Add(err); _IsRunning = false; AddToLogFile(String.Format("{0} {1}", ConnectionName, err.Message)); AddToLogFile(err.StackTrace.ToString()); LastRunReplication = DateTime.Now; } finally { IndicateNotHanging(); } return(true); }
// 启动一般监控任务 public static void StartMonitorTask() { if (_monitorTask != null) { return; } PerdayTask.StartPerdayTask(); CancellationToken token = _cancel.Token; // bool download_complete = false; token.Register(() => { _eventMonitor.Set(); }); _monitorTask = Task.Factory.StartNew(async() => { WpfClientInfo.WriteInfoLog("书柜监控专用线程开始"); try { while (token.IsCancellationRequested == false) { // await Task.Delay(TimeSpan.FromSeconds(10)); _eventMonitor.WaitOne(_monitorIdleLength); token.ThrowIfCancellationRequested(); // *** // 关闭天线射频 if (_tagAdded) { _ = Task.Run(async() => { try { await SelectAntennaAsync(); } catch (Exception ex) { WpfClientInfo.WriteErrorLog($"关闭天线射频 SelectAntennaAsync() 时出现异常: {ExceptionUtil.GetDebugText(ex)}"); } }); _tagAdded = false; } if (DateTime.Now - _lastDetectTime > _detectPeriod) { DetectLibraryNetwork(); _lastDetectTime = DateTime.Now; } // 提醒关门 WarningCloseDoor(); // 下载或同步读者信息 string startDate = LoadStartDate(); if (/*download_complete == false || */ string.IsNullOrEmpty(startDate) && _replicatePatronError == 0) { // 如果 Config 中没有记载断点位置,说明以前从来没有首次同步过。需要进行一次首次同步 if (string.IsNullOrEmpty(startDate)) { // SaveStartDate(""); var repl_result = await PatronReplication.DownloadAllPatronRecordAsync( (text) => { WpfClientInfo.WriteInfoLog(text); PageShelf.TrySetMessage(null, text); }, token); if (repl_result.Value == -1) { // TODO: 判断通讯出错的错误码。如果是通讯出错,则稍后需要重试下载 _replicatePatronError++; } else { SaveStartDate(repl_result.StartDate); } // 立刻允许接着做一次零星同步 ActivateMonitor(); } // download_complete = true; } else { // 进行零星同步 if (DateTime.Now - _lastReplicateTime > _replicatePeriod) { // string startDate = LoadStartDate(); // testing // startDate = "20200507:0-"; if (string.IsNullOrEmpty(startDate) == false) { string endDate = DateTimeUtil.DateTimeToString8(DateTime.Now); // parameters: // strLastDate 处理中断或者结束时返回最后处理过的日期 // last_index 处理或中断返回时最后处理过的位置。以后继续处理的时候可以从这个偏移开始 // return: // -1 出错 // 0 中断 // 1 完成 ReplicationResult repl_result = await PatronReplication.DoReplication( startDate, endDate, LogType.OperLog, token); if (repl_result.Value == -1) { WpfClientInfo.WriteErrorLog($"同步出错: {repl_result.ErrorInfo}"); } else if (repl_result.Value == 1) { string lastDate = repl_result.LastDate + ":" + repl_result.LastIndex + "-"; // 注意 - 符号不能少。少了意思就会变成每次只获取一条日志记录了 SaveStartDate(lastDate); } _lastReplicateTime = DateTime.Now; } } } } _monitorTask = null; } catch (OperationCanceledException) { } catch (Exception ex) { WpfClientInfo.WriteErrorLog($"书柜监控专用线程出现异常: {ExceptionUtil.GetDebugText(ex)}"); App.SetError("shelf_monitor", $"书柜监控专用线程出现异常: {ex.Message}"); } finally { WpfClientInfo.WriteInfoLog("书柜监控专用线程结束"); } }, token, TaskCreationOptions.LongRunning, TaskScheduler.Default); }
protected internal sealed override IEnumerable <Replicable> ReplicationOperationComplete(StatefulServiceExecutionContext executionContext, ReplicationResult result, ReplicationOperation replicationOperation) { if (this.IsDisposed) { AppTrace.TraceMsg(TraceLogEventType.Information, "StatefulServiceReplicaT.ReplicationOperationComplete", "ReplicationOperationComplete called after service was disposed"); return(Enumerable.Empty <Replicable>()); } StatefulProgramInstance instance = null; Replicable <StatefulProgramInstance> replicableToCommit = replicationOperation.Replicables.FirstOrDefault() as Replicable <StatefulProgramInstance>; if (replicableToCommit != null) { instance = this.instanceManager.GetInstance(replicableToCommit.Value.Id) as StatefulProgramInstance; if (instance != null) { instance.SetContextInstanceId(); } else if (replicableToCommit.Value != null) { Debug.Assert(replicationOperation.Type == ReplicationOperationType.Evict, "Unexpected operation type"); replicableToCommit.Value.SetContextInstanceId(); } else { Debug.Assert(false, "replicableToCommit.Value is null"); } } AppTrace.TraceMsg( TraceLogEventType.Information, "StatefulComponent.ReplicationOperationComplete", "replicationOperation.Type={0}, result={1}, replicables.Count={2}, replicableToCommit={3}, programInstance={4}", replicationOperation.Type, result, replicationOperation.Replicables.Count(), replicableToCommit != null ? replicableToCommit.Name : "Null", instance != null ? instance.Id : "Null"); IEnumerable <Replicable> replicablesToCommit = null; if (replicationOperation.Type == ReplicationOperationType.Replicate) { if (result == ReplicationResult.Success) { List <Replicable> changes = new List <Replicable>(); if (replicableToCommit.IsDisposed) { foreach (Replicable replicable in replicableToCommit.Value.DataContractReplicables) { changes.Add(replicable); } } else { ItemCollection <string, Replicable> replicables; using (instance.GetReplicables(LockPermission.Write, out replicables)) { foreach (Replicable replicable in replicableToCommit.Value.DataContractReplicables) { if (replicables.Contains(replicable.Name)) { replicables.Remove(replicable.Name); replicables.Add(replicable); } else { replicables.Add(replicable); } changes.Add(replicable); } } } replicablesToCommit = changes; } else { if (instance != null) { AppTrace.TraceMsg(TraceLogEventType.Error, "StatefulServiceReplicaT.ReplicationOperationComplete", "Recycling StatefulProgramInstance with id '{0}'", instance.Id); instance.RecycleInstance(); } replicablesToCommit = base.ReplicationOperationComplete(executionContext, result, replicationOperation); } } if (replicablesToCommit == null) { replicablesToCommit = base.ReplicationOperationComplete(executionContext, result, replicationOperation); } return(replicablesToCommit); }
static void Main(string[] args) { Console.WriteLine("Microsoft (R) UDDI Monitor Utility"); Console.WriteLine("Copyright (C) Microsoft Corp. 2002. All rights reserved.\r\n"); try { ProcessCommandLine(args); ArrayList results = new ArrayList(); ConnectionManager.Open(false, false); // // Get the list of known operatorNodes. // OperatorNodeCollection operatorNodes = new OperatorNodeCollection(); operatorNodes.Get(); // // Get the last notification message status for each operator. // foreach (OperatorNode operatorNode in operatorNodes) { ReplicationResult result = new ReplicationResult(); result.GetLast(operatorNode.OperatorNodeID, true); results.Add(result); } // // Monitor changes to operator status every 5 seconds. // while (true) { Console.WriteLine("Polling for new notifications: {0}. Press Ctrl+C to stop.", DateTime.Now); for (int i = 0; i < operatorNodes.Count; i++) { ReplicationResult lastResult = (ReplicationResult)results[i]; ReplicationResult result = new ReplicationResult(); result.GetLast(operatorNodes[i].OperatorNodeID, true); // // Check to see if a notification message has been received // if (result.LastChange > lastResult.LastChange) { DateTime time = new DateTime(result.LastChange); Console.WriteLine( "\r\n\tnotify_changeRecordsAvailable detected\r\n\t\tNode: {0}\r\n\t\tTime: {1}", result.OperatorNodeID, time); // // Execute the specified file. // Console.WriteLine( "\t\tStarting: {0} -o {1}", Program, result.OperatorNodeID); Process process = Process.Start(Program, "-o " + result.OperatorNodeID); process.WaitForExit(); Console.WriteLine( "\t\tReturn code: {0}\r\n", process.ExitCode); // // Save the current notify result so that we don't // reprocess. // results[i] = result; } } System.Threading.Thread.Sleep(PollInterval); } } catch (CommandLineException e) { if (null != e.Message && e.Message.Length > 0) { Console.WriteLine(e.Message); Console.WriteLine(); } else { DisplayUsage(); } } catch (Exception e) { Console.WriteLine("Exception: {0}", e.ToString()); } finally { ConnectionManager.Close(); } return; }
// 启动一般监控任务 public static void StartMonitorTask() { if (_monitorTask != null) { return; } CancellationToken token = _cancel.Token; bool download_complete = false; token.Register(() => { _eventMonitor.Set(); }); _monitorTask = Task.Factory.StartNew(async() => { WpfClientInfo.WriteInfoLog("监控专用线程开始"); try { while (token.IsCancellationRequested == false) { // await Task.Delay(TimeSpan.FromSeconds(10)); _eventMonitor.WaitOne(_monitorIdleLength); token.ThrowIfCancellationRequested(); // *** // 关闭天线射频 if (_tagAdded) { _ = Task.Run(async() => { try { await SelectAntennaAsync(); } catch (Exception ex) { WpfClientInfo.WriteErrorLog($"关闭天线射频 SelectAntennaAsync() 时出现异常: {ExceptionUtil.GetDebugText(ex)}"); } }); _tagAdded = false; } if (DateTime.Now - _lastDetectTime > _detectPeriod) { DetectLibraryNetwork(); _lastDetectTime = DateTime.Now; } // 提醒关门 WarningCloseDoor(); // 下载或同步读者信息 string startDate = LoadStartDate(); if (/*download_complete == false || */ string.IsNullOrEmpty(startDate)) { // 如果 Config 中没有记载断点位置,说明以前从来没有首次同步过。需要进行一次首次同步 if (string.IsNullOrEmpty(startDate)) { // SaveStartDate(""); var repl_result = await PatronReplication.DownloadAllPatronRecordAsync(token); if (repl_result.Value == -1) { // TODO: 判断通讯出错的错误码。如果是通讯出错,则稍后需要重试下载 } else { SaveStartDate(repl_result.StartDate); } // 立刻允许接着做一次零星同步 ActivateMonitor(); } // download_complete = true; } else { // 进行零星同步 if (DateTime.Now - _lastReplicateTime > _replicatePeriod) { // string startDate = LoadStartDate(); // testing // startDate = "20200507:0-"; if (string.IsNullOrEmpty(startDate) == false) { string endDate = DateTimeUtil.DateTimeToString8(DateTime.Now); // parameters: // strLastDate 处理中断或者结束时返回最后处理过的日期 // last_index 处理或中断返回时最后处理过的位置。以后继续处理的时候可以从这个偏移开始 // return: // -1 出错 // 0 中断 // 1 完成 ReplicationResult repl_result = PatronReplication.DoReplication( startDate, endDate, LogType.OperLog, token); if (repl_result.Value == -1) { WpfClientInfo.WriteErrorLog($"同步出错: {repl_result.ErrorInfo}"); } else if (repl_result.Value == 1) { string lastDate = repl_result.LastDate + ":" + repl_result.LastIndex + "-"; // 注意 - 符号不能少。少了意思就会变成每次只获取一条日志记录了 SaveStartDate(lastDate); } _lastReplicateTime = DateTime.Now; } } } // 检查升级 dp2ssl if (_updated == false // && StringUtil.IsDevelopMode() == false && ApplicationDeployment.IsNetworkDeployed == false && DateTime.Now - _lastUpdateTime > _updatePeriod) { WpfClientInfo.WriteInfoLog("开始自动检查升级"); // result.Value: // -1 出错 // 0 经过检查发现没有必要升级 // 1 成功 // 2 成功,但需要立即重新启动计算机才能让复制的文件生效 var update_result = await GreenInstaller.InstallFromWeb("http://dp2003.com/dp2ssl/v1_dev", "c:\\dp2ssl", "delayExtract,updateGreenSetupExe", //true, //true, token, null); if (update_result.Value == -1) { WpfClientInfo.WriteErrorLog($"自动检查升级出错: {update_result.ErrorInfo}"); } else { WpfClientInfo.WriteInfoLog($"结束自动检查升级 update_result:{update_result.ToString()}"); } if (update_result.Value == 1 || update_result.Value == 2) { App.TriggerUpdated("重启可使用新版本"); _updated = true; PageShelf.TrySetMessage(null, "dp2SSL 升级文件已经下载成功,下次重启时可自动升级到新版本"); } _lastUpdateTime = DateTime.Now; } } _monitorTask = null; } catch (OperationCanceledException) { } catch (Exception ex) { WpfClientInfo.WriteErrorLog($"监控专用线程出现异常: {ExceptionUtil.GetDebugText(ex)}"); App.SetError("monitor", $"监控专用线程出现异常: {ex.Message}"); } finally { WpfClientInfo.WriteInfoLog("监控专用线程结束"); } }, token, TaskCreationOptions.LongRunning, TaskScheduler.Default); }