From 86a17cf748e9c027164100bb495d91414f4220f7 Mon Sep 17 00:00:00 2001
From: Petar Hristov <hristov@itc.rwth-aachen.de>
Date: Fri, 16 Dec 2022 10:53:57 +0100
Subject: [PATCH] Fix: Added Request Wrapper to prevent SPARQL Timeouts

---
 src/GraphDeployer/GraphDeployer.csproj |  1 +
 src/GraphDeployer/Helpers.cs           | 35 ++++++++++++++++++++++++++
 src/GraphDeployer/Program.cs           |  8 +++---
 3 files changed, 40 insertions(+), 4 deletions(-)
 create mode 100644 src/GraphDeployer/Helpers.cs

diff --git a/src/GraphDeployer/GraphDeployer.csproj b/src/GraphDeployer/GraphDeployer.csproj
index 9860621..fa9711d 100644
--- a/src/GraphDeployer/GraphDeployer.csproj
+++ b/src/GraphDeployer/GraphDeployer.csproj
@@ -27,6 +27,7 @@
 		<PackageReference Include="LibGit2Sharp" Version="0.26.2" />
 		<PackageReference Include="NLog" Version="5.1.0" />
 		<PackageReference Include="NLog.Extensions.Logging" Version="5.2.0" />
+		<PackageReference Include="Polly.Extensions.Http" Version="3.0.0" />
 	</ItemGroup>
 
 	<ItemGroup>
diff --git a/src/GraphDeployer/Helpers.cs b/src/GraphDeployer/Helpers.cs
new file mode 100644
index 0000000..bc5e66b
--- /dev/null
+++ b/src/GraphDeployer/Helpers.cs
@@ -0,0 +1,35 @@
+using Polly;
+
+namespace Coscine.GraphDeployer;
+
+public static class Helpers
+{
+    /// <summary>
+    /// Retry Virtuoso Requests since they sometimes just fail
+    /// </summary>
+    /// <typeparam name="W"></typeparam>
+    /// <param name="function"></param>
+    /// <returns></returns>
+    public static void WrapRequest(Action action)
+    {
+        Policy
+            .Handle<Exception>()
+            .WaitAndRetry(5, retryNumber => TimeSpan.FromMilliseconds(200))
+            .Execute(() => action.Invoke());
+    }
+
+    /// <summary>
+    /// Retry Virtuoso Requests since they sometimes just fail
+    /// </summary>
+    /// <typeparam name="W"></typeparam>
+    /// <param name="function"></param>
+    /// <returns></returns>
+    public static W WrapRequest<W>(Func<W> function)
+    {
+        return Policy
+            .Handle<Exception>()
+            .WaitAndRetry(5, retryNumber => TimeSpan.FromMilliseconds(200))
+            .ExecuteAndCapture(() => function.Invoke()).Result;
+    }
+
+}
diff --git a/src/GraphDeployer/Program.cs b/src/GraphDeployer/Program.cs
index f753bfe..3ff8947 100644
--- a/src/GraphDeployer/Program.cs
+++ b/src/GraphDeployer/Program.cs
@@ -100,7 +100,7 @@ public class Program
                     {
                         graphAccumulation[graph.BaseUri].Item1.Merge(graph);
                         graphAccumulation[graph.BaseUri].Item2.Add(file);
-                    } 
+                    }
                     else
                     {
                         graphAccumulation.Add(graph.BaseUri, (graph, new List<string>() { file }));
@@ -112,19 +112,19 @@ public class Program
                     var graph = kv.Value.Item1;
                     var graphName = kv.Key.ToString();
 
-                    var currentGraph = _rdfStoreConnector.GetGraph(graphName);
+                    var currentGraph = Helpers.WrapRequest(() => _rdfStoreConnector.GetGraph(graphName));
 
                     var graphWasChanged = graph.Triples.Count != currentGraph.Triples.Count
                         || graph.Triples.Any((triple) => !currentGraph.Triples.Any((currentTriple) =>
                             (triple.Subject.Equals(currentTriple.Subject) || (triple.Subject.NodeType == NodeType.Blank && currentTriple.Subject.NodeType == NodeType.Blank)
-                            && triple.Predicate.Equals(currentTriple.Predicate) 
+                            && triple.Predicate.Equals(currentTriple.Predicate)
                             && triple.Object.Equals(currentTriple.Object) || (triple.Object.NodeType == NodeType.Blank && currentTriple.Object.NodeType == NodeType.Blank))));
 
                     if (graphWasChanged)
                     {
                         if (!currentGraph.IsEmpty)
                         {
-                            _rdfStoreConnector.ClearGraph(graphName);
+                            Helpers.WrapRequest(() => _rdfStoreConnector.ClearGraph(graphName));
                             _logger.LogInformation("Cleared Graph {graphName}", graphName);
                         }
                         else
-- 
GitLab