Sfoglia il codice sorgente

Modified Migration2 to simplify log initialisation.
Improved check to see if logs need to be downloaded if the database is recreated.
Split log synchronisation into separate log download and upload threads.
Switch from lastBatchId to minBatchId for /api/batches/ call.

Brett Credo 8 anni fa
parent
commit
fbe8ba0536

+ 1 - 1
BulkPrinting/BulkPrinting/BatchForm.cs

318
                                 Log.Debug("Querying batches");
318
                                 Log.Debug("Querying batches");
319
 
319
 
320
                                 Page<Batch> BatchPage = new Page<Batch>();
320
                                 Page<Batch> BatchPage = new Page<Batch>();
321
-                                if (Utility.RESTRequest(ref BatchPage, String.Format("/api/batches/?lastBatchId={0}", lastSyncedBatchId)))
321
+                                if (Utility.RESTRequest(ref BatchPage, String.Format("/api/batches/?minBatchId={0}", lastSyncedBatchId + 1)))
322
                                 {
322
                                 {
323
                                     if (BatchPage.Items.Count == 0)
323
                                     if (BatchPage.Items.Count == 0)
324
                                     {
324
                                     {

+ 7 - 3
BulkPrinting/BulkPrinting/Globals.cs

26
         public static Printer MaxPrinter;
26
         public static Printer MaxPrinter;
27
         public static List<int> OpenBatches;
27
         public static List<int> OpenBatches;
28
         public static UserLimits UserCurrentUsage;
28
         public static UserLimits UserCurrentUsage;
29
-        public static EventWaitHandle LogSyncThreadEvent;
30
-        public static Thread LogSyncThread;
31
-        public static bool LogSyncThreadAborted;
29
+        public static Thread LogUploadThread;
30
+        public static object LogUploadThreadLock = new object();
31
+        public static bool LogUploadThreadCancelled;
32
+        public static bool UploadNewLogs;
33
+        public static Thread LogDownloadThread;
34
+        public static object LogDownloadThreadLock = new object();
35
+        public static bool LogDownloadThreadCancelled;
32
     }
36
     }
33
 }
37
 }

+ 2 - 0
BulkPrinting/BulkPrinting/Migrations.cs

147
                 "UPDATE Parameters SET Value='2' WHERE Key='Migration'",
147
                 "UPDATE Parameters SET Value='2' WHERE Key='Migration'",
148
                 "UPDATE Batch SET Downloaded=(ReadyForDownload=1 AND DeliveredQuantity<=COALESCE((SELECT COUNT(*) FROM Voucher WHERE Voucher.BatchId=Batch.Id), 0))",
148
                 "UPDATE Batch SET Downloaded=(ReadyForDownload=1 AND DeliveredQuantity<=COALESCE((SELECT COUNT(*) FROM Voucher WHERE Voucher.BatchId=Batch.Id), 0))",
149
                 "INSERT INTO Parameters (Key, Value) VALUES ('LastSyncedBatchId', '0')",
149
                 "INSERT INTO Parameters (Key, Value) VALUES ('LastSyncedBatchId', '0')",
150
+                "INSERT INTO Parameters (Key, Value) VALUES ('SyncBackwardsFromLogId', '0')",
151
+                "INSERT INTO Parameters (Key, Value) VALUES ('LoggingInitialised', '" + false.ToString() + "')",
150
                 "CREATE TABLE Logs_New (" +
152
                 "CREATE TABLE Logs_New (" +
151
                     "Id INTEGER PRIMARY KEY AUTOINCREMENT," +
153
                     "Id INTEGER PRIMARY KEY AUTOINCREMENT," +
152
                     "UserId INT NOT NULL," +
154
                     "UserId INT NOT NULL," +

+ 3 - 2
BulkPrinting/BulkPrinting/UserLoginForm.cs

121
                             Globals.DBConnection = Utility.OpenDBConnection();
121
                             Globals.DBConnection = Utility.OpenDBConnection();
122
                         }
122
                         }
123
                         Migrations.CheckMigrations(Globals.DBConnection);
123
                         Migrations.CheckMigrations(Globals.DBConnection);
124
-                        Utility.CheckLastSyncedLogID(Globals.DBConnection);
125
-                        Utility.TriggerLogSync(); //Perform log sync before any logging happens to ensure synchronicity with server
124
+                        Utility.CheckLogSynchronisation(Globals.DBConnection);
125
+                        Utility.TriggerLogDownload();
126
+                        Utility.TriggerLogUpload();
126
                     }
127
                     }
127
                 }
128
                 }
128
             }
129
             }

+ 228 - 101
BulkPrinting/BulkPrinting/Utility.cs

391
 
391
 
392
         public static int GetSavedParameterAsInt(SQLiteConnection conn, string key)
392
         public static int GetSavedParameterAsInt(SQLiteConnection conn, string key)
393
         {
393
         {
394
-            return int.Parse(GetSavedParameter(conn, key));
394
+            return Convert.ToInt32(GetSavedParameter(conn, key));
395
+        }
396
+
397
+        public static bool GetSavedParameterAsBoolean(SQLiteConnection conn, string key)
398
+        {
399
+            return Convert.ToBoolean(GetSavedParameter(conn, key));
395
         }
400
         }
396
 
401
 
397
         public static bool UpdateSavedParameter(SQLiteConnection conn, string key, object value)
402
         public static bool UpdateSavedParameter(SQLiteConnection conn, string key, object value)
399
             return DBExecuteNonQuery(conn,
404
             return DBExecuteNonQuery(conn,
400
                 "UPDATE Parameters SET Value=@Value WHERE Key=@Key",
405
                 "UPDATE Parameters SET Value=@Value WHERE Key=@Key",
401
                 new SQLiteParameter("@Key", key),
406
                 new SQLiteParameter("@Key", key),
402
-                new SQLiteParameter("@Value", value)) > 0;
407
+                new SQLiteParameter("@Value", Convert.ToString(value))) > 0;
403
         }
408
         }
404
 
409
 
405
         public static void PrintVouchers(SQLiteConnection conn, int BatchId, int StartSeqNo, int EndSeqNo)
410
         public static void PrintVouchers(SQLiteConnection conn, int BatchId, int StartSeqNo, int EndSeqNo)
560
                     new SQLiteParameter("@key", "SessionDataJson"),
565
                     new SQLiteParameter("@key", "SessionDataJson"),
561
                     new SQLiteParameter("@value", SessionDataJson));
566
                     new SQLiteParameter("@value", SessionDataJson));
562
                 LogEvent(Globals.DBConnection, VendorEvent.VendorEventType.Logout);
567
                 LogEvent(Globals.DBConnection, VendorEvent.VendorEventType.Logout);
563
-                if (Globals.LogSyncThread != null)
568
+
569
+                CancelLogUploadWorker();
570
+                CancelLogDownloadWorker();
571
+
572
+                if (Globals.LogUploadThread != null)
564
                 {
573
                 {
565
-                    Globals.LogSyncThreadAborted = true;
566
-                    Globals.LogSyncThreadEvent.Set();
567
-                    if (Globals.LogSyncThread.IsAlive)
568
-                    {
569
-                        Globals.LogSyncThread.Join();
570
-                    }
571
-                    Globals.LogSyncThread = null;
574
+                    Globals.LogUploadThread.Join();
575
+                    Globals.LogUploadThread = null;
576
+                }
577
+                if (Globals.LogDownloadThread != null)
578
+                {
579
+                    Globals.LogDownloadThread.Join();
580
+                    Globals.LogDownloadThread = null;
572
                 }
581
                 }
573
 
582
 
583
+                Globals.UploadNewLogs = false;
584
+
574
                 Globals.DBConnection.Close();
585
                 Globals.DBConnection.Close();
575
                 Globals.SessionData = null;
586
                 Globals.SessionData = null;
576
                 Globals.SessionDatabasePassword = null;
587
                 Globals.SessionDatabasePassword = null;
592
             return (int)MetaData.LastVendorEventRemoteId;
603
             return (int)MetaData.LastVendorEventRemoteId;
593
         }
604
         }
594
 
605
 
595
-        public static void CheckLastSyncedLogID(SQLiteConnection conn)
606
+        public static void CheckLogSynchronisation(SQLiteConnection conn)
596
         {
607
         {
597
-            int lastSyncedLogId = GetLastSyncedLogID();
598
-            if (lastSyncedLogId == 0)
608
+            if (!GetSavedParameterAsBoolean(conn, "LoggingInitialised"))
599
             {
609
             {
600
-                return;
610
+                var lastSyncedLogId = GetLastSyncedLogID();
611
+
612
+                // If we already have logs then there is no need to synchronise.
613
+                // NOTE: logs are synchronised in reverse from SyncBackwardsFromLogId downwards
614
+                if ((long)DBExecuteScalar(conn, "SELECT COUNT(*) FROM Logs") == 0)
615
+                {
616
+                    UpdateSavedParameter(conn, "SyncBackwardsFromLogId", lastSyncedLogId);
617
+                }
618
+
619
+                // If there are logs on the server then ensure that the log autoincrement value is set to the last
620
+                // log ID received by the server so new local logs don't clash with existing log entries on the server.
621
+                if (lastSyncedLogId != 0)
622
+                {
623
+                    lock (Globals.DBWriteLock)
624
+                    {
625
+                        using (var trans = conn.BeginTransaction())
626
+                        {
627
+                            using (var command = new SQLiteCommand(conn))
628
+                            {
629
+                                command.Transaction = trans;
630
+                                command.Parameters.AddWithValue("@Id", lastSyncedLogId);
631
+
632
+                                command.CommandText = "UPDATE sqlite_sequence SET seq=CASE WHEN IFNULL(seq, 0)<@Id THEN @Id ELSE seq END WHERE name='Logs'";
633
+                                if (command.ExecuteNonQuery() == 0)
634
+                                {
635
+                                    command.CommandText = "INSERT INTO sqlite_sequence (name, seq) VALUES ('Logs', @id)";
636
+                                    command.ExecuteNonQuery();
637
+                                }
638
+                            }
639
+                            trans.Commit();
640
+                        }
641
+                    }
642
+                }
643
+
644
+                UpdateSavedParameter(conn, "LoggingInitialised", true);
601
             }
645
             }
602
-            lock (Globals.DBWriteLock)
646
+        }
647
+
648
+        public static void CancelLogDownloadWorker()
649
+        {
650
+            lock (Globals.LogDownloadThreadLock)
603
             {
651
             {
604
-                using (var trans = conn.BeginTransaction())
652
+                Globals.LogDownloadThreadCancelled = true;
653
+                Monitor.Pulse(Globals.LogDownloadThreadLock);
654
+            }
655
+        }
656
+
657
+        public static void LogDownloadWorker()
658
+        {
659
+            const int vendorEventPageSize = 1000;
660
+            const int retryInterval = 30000;
661
+
662
+            var conn = Globals.DBConnection;
663
+            //using (var conn = OpenDBConnection())
664
+            {
665
+                bool cancelled = false;
666
+                int maxRemoteId = GetSavedParameterAsInt(conn, "SyncBackwardsFromLogId");
667
+                while (!cancelled && (maxRemoteId > 0))
605
                 {
668
                 {
606
-                    using (var command = new SQLiteCommand(conn))
669
+                    var EventPage = new Page<VendorEvent>();
670
+                    if (RESTRequest(ref EventPage, String.Format("/api/vendorevents/?maxRemoteId={0}&pageSize={1}", maxRemoteId, vendorEventPageSize)))
607
                     {
671
                     {
608
-                        command.Transaction = trans;
609
-                        command.Parameters.AddWithValue("@Id", lastSyncedLogId);
672
+                        lock (Globals.DBWriteLock)
673
+                        {
674
+                            using (var trans = conn.BeginTransaction())
675
+                            {
676
+                                using (var insertCommand = new SQLiteCommand(
677
+                                    "INSERT INTO Logs (Id,  UserId,  VoucherId,  EventDate,  EventType,  Retry) " +
678
+                                              "VALUES (@id, @userid, @voucherid, @eventdate, @eventtype, @retry)",
679
+                                    conn, trans))
680
+                                using (var updateCommand = new SQLiteCommand(
681
+                                    "UPDATE Parameters SET Value=@Value WHERE Key='SyncBackwardsFromLogId'",
682
+                                    conn, trans))
683
+                                {
684
+                                    foreach (VendorEvent Event in EventPage.Items)
685
+                                    {
686
+                                        if (!Event.RemoteId.HasValue)
687
+                                        {
688
+                                            throw new Exception("Downloaded event with no remote ID");
689
+                                        }
690
+                                        else if (Event.RemoteId.Value > maxRemoteId)
691
+                                        {
692
+                                            throw new Exception("Downloaded event remote ID was not in descending order");
693
+                                        }
610
 
694
 
611
-                        command.CommandText = "UPDATE sqlite_sequence SET seq=CASE WHEN IFNULL(seq, 0)<@Id THEN @Id ELSE seq END WHERE name='Logs'";
612
-                        if (command.ExecuteNonQuery() == 0)
695
+                                        insertCommand.Parameters.Clear();
696
+                                        insertCommand.Parameters.AddWithValue("@id", Event.RemoteId);
697
+                                        insertCommand.Parameters.AddWithValue("@userid", Event.UserId);
698
+                                        insertCommand.Parameters.AddWithValue("@voucherid", Event.VoucherId);
699
+                                        insertCommand.Parameters.AddWithValue("@eventdate", Event.EventDate.UtcDateTime);
700
+                                        insertCommand.Parameters.AddWithValue("@eventtype", Event.EventType);
701
+                                        insertCommand.Parameters.AddWithValue("@retry", Event.Retry);
702
+                                        insertCommand.ExecuteNonQuery();
703
+
704
+                                        maxRemoteId = Event.RemoteId.Value - 1;
705
+                                    }
706
+
707
+                                    updateCommand.Parameters.Clear();
708
+                                    updateCommand.Parameters.AddWithValue("@Value", maxRemoteId.ToString());
709
+                                    updateCommand.ExecuteNonQuery();
710
+                                }
711
+
712
+                                trans.Commit();
713
+                            }
714
+                        }
715
+
716
+                        lock (Globals.LogDownloadThreadLock)
613
                         {
717
                         {
614
-                            command.CommandText = "INSERT INTO sqlite_sequence (name, seq) VALUES ('Logs', @id)";
615
-                            command.ExecuteNonQuery();
718
+                            cancelled = Globals.LogDownloadThreadCancelled;
719
+                        }
720
+                    }
721
+                    else
722
+                    {
723
+                        lock (Globals.LogDownloadThreadLock)
724
+                        {
725
+                            if (!Globals.LogDownloadThreadCancelled)
726
+                            {
727
+                                Monitor.Wait(Globals.LogDownloadThreadLock, retryInterval);
728
+                            }
729
+                            cancelled = Globals.LogDownloadThreadCancelled;
616
                         }
730
                         }
617
                     }
731
                     }
618
-                    trans.Commit();
619
                 }
732
                 }
620
             }
733
             }
621
         }
734
         }
622
 
735
 
623
-        public static bool SyncLogsWorker()
736
+        public static void TriggerLogDownload()
624
         {
737
         {
738
+            if (Globals.LogDownloadThread == null)
739
+            {
740
+                Globals.LogDownloadThread = new Thread(() => LogDownloadWorker());
741
+                Globals.LogDownloadThread.Start();
742
+            }
743
+        }
744
+
745
+        public static void CancelLogUploadWorker()
746
+        {
747
+            lock (Globals.LogUploadThreadLock)
748
+            {
749
+                Globals.LogUploadThreadCancelled = true;
750
+                Monitor.Pulse(Globals.LogUploadThreadLock);
751
+            }
752
+        }
753
+
754
+        public static void LogUploadWorker()
755
+        {
756
+            const int uploadPageSize = 1000;
757
+            var retryInterval = 30000;
758
+
625
             var conn = Globals.DBConnection;
759
             var conn = Globals.DBConnection;
626
             //using (var conn = OpenDBConnection())
760
             //using (var conn = OpenDBConnection())
627
             {
761
             {
628
-                while (Globals.LogSyncThreadEvent.WaitOne() && !Globals.LogSyncThreadAborted)
762
+                var cancelled = false;
763
+                while (! cancelled)
629
                 {
764
                 {
630
-                    int LastSyncedLogID = GetLastSyncedLogID();
765
+                    var uploadFailed = false;
766
+                    int lastSyncedLogId = GetLastSyncedLogID();
631
 
767
 
632
                     var result = DBExecuteScalar(conn, "SELECT MAX(Id) FROM Logs")?.ToString() ?? "0";
768
                     var result = DBExecuteScalar(conn, "SELECT MAX(Id) FROM Logs")?.ToString() ?? "0";
633
-                    if (string.IsNullOrWhiteSpace(result)) result = "0";
634
-
635
-                    int LastRecordedLogId = int.Parse(result.ToString());
636
-                    if (LastRecordedLogId > LastSyncedLogID)
637
-                    { //If local logs are newer than server logs
638
-                        List<RemoteVendorEvent> EventList = new List<RemoteVendorEvent>();
639
-                        RemoteVendorEvent NextEvent;
640
-                        RemoteVendorEventResponse LastVendorEventIdSynced;
641
-                        int Counter = 0;
769
+                    if (string.IsNullOrWhiteSpace(result))
770
+                    {
771
+                        result = "0";
772
+                    }
773
+                    int lastRecordedLogId = int.Parse(result.ToString());
774
+
775
+                    if (lastRecordedLogId > lastSyncedLogId)
776
+                    {
777
+                        List<RemoteVendorEvent> eventList = new List<RemoteVendorEvent>();
778
+                        int counter = 0;
642
                         using (var Command = new SQLiteCommand("Select Id,UserId,VoucherId,EventDate,EventType From Logs WHERE Id > @id", conn))
779
                         using (var Command = new SQLiteCommand("Select Id,UserId,VoucherId,EventDate,EventType From Logs WHERE Id > @id", conn))
643
                         {
780
                         {
644
-                            Command.Parameters.AddWithValue("@id", LastSyncedLogID);
781
+                            Command.Parameters.AddWithValue("@id", lastSyncedLogId);
645
                             using (SQLiteDataReader read = Command.ExecuteReader())
782
                             using (SQLiteDataReader read = Command.ExecuteReader())
646
                             {
783
                             {
647
                                 while (read.Read())
784
                                 while (read.Read())
648
                                 {
785
                                 {
649
-                                    Counter += 1;
650
-                                    NextEvent = new RemoteVendorEvent();
651
-                                    NextEvent.Id = read.GetInt32(0);
652
-                                    NextEvent.UserId = read.GetInt32(1);
786
+                                    counter += 1;
787
+                                    var nextEvent = new RemoteVendorEvent();
788
+                                    nextEvent.Id = read.GetInt32(0);
789
+                                    nextEvent.UserId = read.GetInt32(1);
653
                                     if (read.IsDBNull(2) == true)
790
                                     if (read.IsDBNull(2) == true)
654
                                     {
791
                                     {
655
-                                        NextEvent.VoucherId = null;
792
+                                        nextEvent.VoucherId = null;
656
                                     }
793
                                     }
657
                                     else
794
                                     else
658
                                     {
795
                                     {
659
-                                        NextEvent.VoucherId = read.GetInt32(2);
796
+                                        nextEvent.VoucherId = read.GetInt32(2);
660
                                     }
797
                                     }
661
-                                    NextEvent.EventDate = (DateTime)read.GetDateTime(3);
662
-                                    NextEvent.EventType = (VendorEvent.VendorEventType)Enum.Parse(typeof(VendorEvent.VendorEventType), read.GetValue(4).ToString());
663
-                                    NextEvent.VendorId = Globals.SessionData.Credentials.Payload.Vendor.id;
664
-                                    EventList.Add(NextEvent);
665
-                                    if (Counter == 1000)
666
-                                    { //Send logs in pages of 1000
667
-                                        LastVendorEventIdSynced = new RemoteVendorEventResponse();
668
-                                        bool EventPostResult = RESTRequest<List<RemoteVendorEvent>, RemoteVendorEventResponse>(EventList, ref LastVendorEventIdSynced, "/api/vendorevents/");
669
-                                        Counter = 0;
670
-                                        EventList = new List<RemoteVendorEvent>();
798
+                                    nextEvent.EventDate = read.GetDateTime(3);
799
+                                    nextEvent.EventType = (VendorEvent.VendorEventType)Enum.Parse(typeof(VendorEvent.VendorEventType), read.GetValue(4).ToString());
800
+                                    nextEvent.VendorId = Globals.SessionData.Credentials.Payload.Vendor.id;
801
+                                    eventList.Add(nextEvent);
802
+
803
+                                    if (counter == uploadPageSize)
804
+                                    {
805
+                                        var response = new RemoteVendorEventResponse();
806
+                                        if (RESTRequest(eventList, ref response, "/api/vendorevents/"))
807
+                                        {
808
+                                            counter = 0;
809
+                                            eventList.Clear();
810
+                                        }
811
+                                        else
812
+                                        {
813
+                                            uploadFailed = true;
814
+                                            break;
815
+                                        }
671
                                     }
816
                                     }
672
                                 }
817
                                 }
673
-                                if (Counter > 0)
674
-                                { //Left over logs not synced in a 100 item page
675
-                                    LastVendorEventIdSynced = new RemoteVendorEventResponse();
676
-                                    bool EventPostResult = RESTRequest<List<RemoteVendorEvent>, RemoteVendorEventResponse>(EventList, ref LastVendorEventIdSynced, "/api/vendorevents/");
818
+                                if (counter > 0)
819
+                                {
820
+                                    var response = new RemoteVendorEventResponse();
821
+                                    if (! RESTRequest(eventList, ref response, "/api/vendorevents/"))
822
+                                    {
823
+                                        uploadFailed = true;
824
+                                    }
677
                                 }
825
                                 }
678
                             }
826
                             }
679
                         }
827
                         }
680
                     }
828
                     }
681
-                    else if (LastSyncedLogID > LastRecordedLogId)
682
-                    { //Server logs are newer than local logs, indicating loss of local database - resync entire table
683
-                        DBExecuteNonQuery(conn, "DELETE FROM Logs");
684
-                        Page<VendorEvent> EventPage;
685
-                        int TotalPages = 1;
686
-                        for (int PageNumber = 1; PageNumber <= TotalPages; PageNumber++)
829
+
830
+                    lock (Globals.LogUploadThreadLock)
831
+                    {
832
+                        while (! Globals.LogUploadThreadCancelled && ! Globals.UploadNewLogs)
687
                         {
833
                         {
688
-                            EventPage = new Page<VendorEvent>();
689
-                            bool EventGetResult = RESTRequest<Page<VendorEvent>>(ref EventPage, String.Format("/api/vendorevents/?page={0}&pagesize=1000", PageNumber));
690
-                            if (TotalPages == 1)
691
-                            { //Number of pages is sent with first page, so update on the fly
692
-                                TotalPages = EventPage.NumPages;
693
-                            }
694
-                            lock (Globals.DBWriteLock)
834
+                            Monitor.Wait(Globals.LogUploadThreadLock, uploadFailed ? retryInterval : Timeout.Infinite);
835
+                            if (uploadFailed)
695
                             {
836
                             {
696
-                                using (var trans = conn.BeginTransaction())
697
-                                {
698
-                                    var Sql = "INSERT INTO Logs (Id, UserId, VoucherId, EventDate, EventType, Retry) VALUES (@id, @userid, @voucherid, @eventdate, @eventtype, @retry)";
699
-                                    using (var cmd = new SQLiteCommand(Sql, conn, trans))
700
-                                    {
701
-                                        foreach (VendorEvent Event in EventPage.Items)
702
-                                        {
703
-                                            if (Event.RemoteId != null) //Only interested in downloading locally generated logs
704
-                                            {
705
-                                                cmd.Parameters.Clear();
706
-                                                cmd.Parameters.AddWithValue("@id", Event.RemoteId);
707
-                                                cmd.Parameters.AddWithValue("@userid", Event.UserId);
708
-                                                cmd.Parameters.AddWithValue("@voucherid", Event.VoucherId);
709
-                                                cmd.Parameters.AddWithValue("@eventdate", Event.EventDate.UtcDateTime);
710
-                                                cmd.Parameters.AddWithValue("@eventtype", Event.EventType);
711
-                                                cmd.Parameters.AddWithValue("@retry", Event.Retry);
712
-                                                cmd.ExecuteNonQuery();
713
-                                            }
714
-                                        }
715
-                                    }
716
-                                    trans.Commit();
717
-                                }
837
+                                break;
718
                             }
838
                             }
719
                         }
839
                         }
840
+                        Globals.UploadNewLogs = false;
841
+                        cancelled = Globals.LogUploadThreadCancelled;
720
                     }
842
                     }
721
                 }
843
                 }
722
             }
844
             }
723
-            return true;
724
         }
845
         }
725
 
846
 
726
-        public static void TriggerLogSync()
847
+        public static void TriggerLogUpload()
727
         {
848
         {
728
-            if (Globals.LogSyncThread == null)
849
+            if (Globals.LogUploadThread == null)
850
+            {
851
+                Globals.LogUploadThread = new Thread(() => LogUploadWorker());
852
+                Globals.LogUploadThread.Start();
853
+            }
854
+            else
729
             {
855
             {
730
-                Globals.LogSyncThreadEvent = new EventWaitHandle(false, EventResetMode.AutoReset);
731
-                Globals.LogSyncThread = new Thread(() => SyncLogsWorker());
732
-                Globals.LogSyncThread.Start();
856
+                lock (Globals.LogUploadThreadLock)
857
+                {
858
+                    Globals.UploadNewLogs = true;
859
+                    Monitor.Pulse(Globals.LogUploadThreadLock);
860
+                }
733
             }
861
             }
734
-            Globals.LogSyncThreadEvent.Set();
735
         }
862
         }
736
 
863
 
737
         public static void LogBulkEvents(SQLiteConnection conn, List<EventLog> EventLogs)
864
         public static void LogBulkEvents(SQLiteConnection conn, List<EventLog> EventLogs)
761
 
888
 
762
             if (Globals.SessionMode == SessionModes.Online)
889
             if (Globals.SessionMode == SessionModes.Online)
763
             {
890
             {
764
-                TriggerLogSync();
891
+                TriggerLogUpload();
765
             }
892
             }
766
         }
893
         }
767
 
894
 
777
                 new SQLiteParameter("@retry", Retry));
904
                 new SQLiteParameter("@retry", Retry));
778
             if (Globals.SessionMode == SessionModes.Online)
905
             if (Globals.SessionMode == SessionModes.Online)
779
             {
906
             {
780
-                TriggerLogSync();
907
+                TriggerLogUpload();
781
             }
908
             }
782
         }
909
         }
783
 
910