Exemplo n.º 1
0
        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 SchemaValidation(DatabaseConnection connection)
     : base(connection, new TimeSpan())
 {
 }