private static void OnAbort() { ExportQueue.Clear(); if (ExportThread != null) { if (ExportThread.IsAlive || ExportThread.ThreadState == ThreadState.Running) { ExportThread.Abort(); ExportThread.Join(3000); } ExportThread = null; } if (_Connection != null && _Connection.Connected) { _Connection.Close(); _Connection = null; } CMOptions.ToConsole("Update aborted."); _Updating = false; }
private static void Cancel() { if (!_Updating) { ExportQueue.Clear(); return; } if (ExportThread != null) { if (ExportThread.IsAlive || ExportThread.ThreadState == ThreadState.Running) { ExportThread.Abort(); ExportThread.Join(3000); } ExportThread = null; } if (_Connection != null) { _Connection.Close(); _Connection = null; } _Updating = false; }
private static void UpdateCallback() { if (_Updating || !Connection.Connected) { return; } _Updating = true; LastUpdate = DateTime.Now; Connection.NonQuery( @"CREATE DATABASE IF NOT EXISTS `{0}` DEFAULT CHARSET `utf8` DEFAULT COLLATE `utf8_bin`", CMOptions.MySQL.Database); Connection.UseDatabase(CMOptions.MySQL.Database); var watch = new Stopwatch(); watch.Start(); VitaNexCore.TryCatch( () => { Process(); Flush(); }, x => { CMOptions.ToConsole(x); OnAbort(); }); watch.Stop(); CMOptions.ToConsole("Updated {0:#,0} objects in {1:F2} seconds.", _UpdateCount, watch.Elapsed.TotalSeconds); if (UpdateTimes.Count >= 10) { UpdateTimes.Dequeue(); } UpdateTimes.Enqueue(watch.Elapsed); ExportQueue.Clear(); if (_Connection != null) { _Connection.Close(); _Connection = null; } //GC.Collect(); _UpdateCount = 0; _Updating = false; }
/// <summary> /// Initializes a new instance of the <see cref="ExportController"/> class. /// </summary> /// <param name="sentNotificationDataRepository">SentNotification data repository instance.</param> /// <param name="exportDataRepository">Export data repository instance.</param> /// <param name="userDataRepository">User data repository instance.</param> /// <param name="exportQueue">The service bus queue for the export queue.</param> public ExportController( SentNotificationDataRepository sentNotificationDataRepository, ExportDataRepository exportDataRepository, UserDataRepository userDataRepository, ExportQueue exportQueue) { this.sentNotificationDataRepository = sentNotificationDataRepository; this.exportDataRepository = exportDataRepository; this.userDataRepository = userDataRepository; this.exportQueue = exportQueue; }
private static void Enqueue <T>(T obj) { if (!_Updating) { OnAbort(); return; } IDictionary <string, SimpleType> data = null; LegendState state = ObjectStates.FirstOrDefault(s => s.Compile(obj, out data)); if (state != null && data != null && data.Count > 0) { ExportQueue.GetOrAdd(state.TableName, new ConcurrentStack <QueuedData>()).Push( new QueuedData { RawData = data, SqlData = data.Select(kd => new MySQLData(kd.Key, SQL.Encode(kd.Value, true))).ToArray() }); } }
private static void FlushCallback(bool transactional) { int total = ExportQueue.Values.Sum(d => d.Count); if (!_Updating || ExportQueue.Count == 0 || total == 0) { if (transactional) { Connection.EndTransaction(); _Sync.Set(); } OnAbort(); return; } CMOptions.ToConsole("{0:#,0} objects in {1:#,0} tables pending update...", total, ExportQueue.Count); int updated = 0; ConcurrentStack <QueuedData> stack; QueuedData[] pop; QueuedData peek; MySQLData[][] batch; int count; var watch = new Stopwatch(); watch.Start(); foreach (string table in ExportQueue.Keys.TakeWhile(table => _Updating && updated < CMOptions.ExportCapacity)) { stack = ExportQueue[table]; if (stack == null || stack.IsEmpty) { ExportQueue.TryRemove(table, out stack); continue; } count = Math.Max(0, Math.Min(CMOptions.ExportCapacity - updated, stack.Count)); if (count == 0) { continue; } pop = new QueuedData[count]; if (stack.TryPopRange(pop) > 0) { peek = pop.FirstOrDefault(p => p != null && p.RawData != null && p.RawData.Count > 0); if (peek == null || !Connection.CreateTable(table, peek.RawData)) { ExportQueue.TryRemove(table, out stack); continue; } batch = pop.AsParallel().Select(qd => qd.SqlData).ToMultiArray(); if (batch.Length > 0) { if (CMOptions.ModuleDebug) { CMOptions.ToConsole("Update {0:#,0} objects in '{1}'...", batch.Length, table); } Connection.InsertMany(table, batch); updated += batch.Length; } } if (stack.IsEmpty) { ExportQueue.TryRemove(table, out stack); } } if (transactional) { VitaNexCore.TryCatch(Connection.EndTransaction, CMOptions.ToConsole); } watch.Stop(); CMOptions.ToConsole("Updated {0:#,0} objects in {1:F2} seconds.", updated, watch.Elapsed.TotalSeconds); _UpdateCount += updated; //GC.Collect(); _Sync.Set(); if (!ExportQueue.IsEmpty) { Flush(); } }