Przeglądaj źródła

Fix GPS engine failures when database goes down

Kenric Nugteren 1 rok temu
rodzic
commit
2ef5fc4f78
1 zmienionych plików z 39 dodań i 19 usunięć
  1. 39 19
      prs.server/Engines/GPS/GPSEngine.cs

+ 39 - 19
prs.server/Engines/GPS/GPSEngine.cs

@@ -18,6 +18,7 @@ using InABox.Rpc;
 using System.Timers;
 using PRS.Shared;
 using PRSServices;
+using com.sun.accessibility.@internal.resources;
 
 namespace PRSServer;
 
@@ -159,6 +160,7 @@ public class GPSEngine : Engine<GPSServerProperties>
 {
     private Listener<SigfoxHandler, SigfoxHandlerProperties> sigfoxListener;
     private OEMListener oemListener;
+    private RpcClientPipeTransport transport;
 
     private GPSDeviceCache DeviceCache = new();
 
@@ -232,6 +234,8 @@ public class GPSEngine : Engine<GPSServerProperties>
 
     private void UpdateServer()
     {
+        if (!transport.IsConnected()) return;
+
         // Cache a set of fifty, so that we're not running baack and forth to the filesystem all the time.
         if(LocationQueueCache.Count == 0)
         {
@@ -249,17 +253,22 @@ public class GPSEngine : Engine<GPSServerProperties>
                 if (exception is not null)
                 {
                     Logger.Send(LogType.Error, "", $"Error saving GPS Tracker Location ({update.AuditTrail}): {CoreUtils.FormatException(exception)}");
+
+                    // We won't delete the file in case of an error; this means though that the queue will be wrong, since the item has been dequeued, so we will clear the queue.
+                    LocationQueueCache.Clear();
+                }
+                else
+                {
+                    try
+                    {
+                        File.Delete(filename);
+                    }
+                    catch
+                    {
+                        // Probably got deleted.
+                    }
                 }
             });
-
-            try
-            {
-                File.Delete(filename);
-            }
-            catch
-            {
-                // Probably got deleted.
-            }
         }
     }
 
@@ -278,9 +287,11 @@ public class GPSEngine : Engine<GPSServerProperties>
         PRSSharedUtils.RegisterClasses();
 
         //ClientFactory.SetClientType(typeof(IPCClient<>), Platform.GPSEngine, Version, DatabaseServerProperties.GetPipeName(Properties.Server,false));
-        var transport = new RpcClientPipeTransport(DatabaseServerProperties.GetPipeName(Properties.Server, true));
+        transport = new RpcClientPipeTransport(DatabaseServerProperties.GetPipeName(Properties.Server, true));
         ClientFactory.SetClientType(typeof(RpcClient<>), Platform.GPSEngine, Version, transport);
+        transport.OnClose += Transport_OnClose;
         CheckConnection();
+        ClientFactory.SetBypass();
 
         UpdateQueue.InitQueueFolder();
 
@@ -297,19 +308,28 @@ public class GPSEngine : Engine<GPSServerProperties>
         StartUpdateServerTask();
     }
 
+    private void Transport_OnClose(IRpcTransport transport, RpcTransportCloseArgs e)
+    {
+        // Try to reconnect when lost connection.
+        if (!_connecting)
+        {
+            CheckConnection();
+        }
+    }
+
+    private bool _connecting = false;
+
     private bool CheckConnection()
     {
-        if (ClientFactory.UserGuid == Guid.Empty)
+        _connecting = true;
+        // Wait for server connection
+        while (!Client.Ping())
         {
-            // Wait for server connection
-            while (!Client.Ping())
-            {
-                Logger.Send(LogType.Error, "", "Database server unavailable. Trying again in 30 seconds...");
-                Task.Delay(30_000).Wait();
-                Logger.Send(LogType.Information, "", "Retrying connection...");
-            }
-            ClientFactory.SetBypass();
+            Logger.Send(LogType.Error, "", "Database server unavailable. Trying again in 30 seconds...");
+            Task.Delay(30_000).Wait();
+            Logger.Send(LogType.Information, "", "Retrying connection...");
         }
+        _connecting = false;
 
         return true;
     }