Skip to content

Commit 99e0e75

Browse files
committed
checking and responding to availability of codex node
1 parent 36cc93e commit 99e0e75

File tree

5 files changed

+80
-26
lines changed

5 files changed

+80
-26
lines changed

ProjectPlugins/CodexClient/CodexNode.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ public override string ToString()
299299

300300
private void InitializePeerNodeId()
301301
{
302-
var debugInfo = Time.Retry(codexAccess.GetDebugInfo, "ensure online");
302+
var debugInfo = codexAccess.GetDebugInfo();
303303
if (!debugInfo.Version.IsValid())
304304
{
305305
throw new Exception($"Invalid version information received from Codex node {GetName()}: {debugInfo.Version}");

Tools/BiblioTech/AdminChecker.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public async Task SendInAdminChannel(string msg)
3535

3636
public async Task SendInAdminChannel(string[] lines)
3737
{
38+
if (adminChannel == null) return;
3839
var chunker = new LineChunker(lines);
3940
var chunks = chunker.GetChunks();
4041
if (!chunks.Any()) return;

Tools/BiblioTech/CodexChecking/CodexTwoWayChecker.cs

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public interface ICheckResponseHandler
1515
Task CouldNotDownloadCid();
1616
Task GiveCidToUser(string cid);
1717
Task GiveDataFileToUser(string fileContent);
18+
Task CodexUnavailable();
1819

1920
Task ToAdminChannel(string msg);
2021
}
@@ -43,7 +44,13 @@ public async Task StartDownloadCheck(ICheckResponseHandler handler, ulong userId
4344
repo.SaveChanges();
4445
}
4546

46-
var cid = await UploadData(check.UniqueData);
47+
var cid = UploadData(check.UniqueData);
48+
if (cid == null)
49+
{
50+
await handler.CodexUnavailable();
51+
return;
52+
}
53+
4754
await handler.GiveCidToUser(cid);
4855
}
4956

@@ -87,7 +94,7 @@ public async Task VerifyUploadCheck(ICheckResponseHandler handler, ulong userId,
8794
return;
8895
}
8996

90-
var manifest = await GetManifest(receivedCid);
97+
var manifest = GetManifest(receivedCid);
9198
if (manifest == null)
9299
{
93100
await handler.CouldNotDownloadCid();
@@ -96,7 +103,12 @@ public async Task VerifyUploadCheck(ICheckResponseHandler handler, ulong userId,
96103

97104
if (IsManifestLengthCompatible(handler, check, manifest))
98105
{
99-
if (await IsContentCorrect(handler, check, receivedCid))
106+
var correct = IsContentCorrect(handler, check, receivedCid);
107+
if (!correct.HasValue) {
108+
await handler.CodexUnavailable();
109+
return;
110+
}
111+
if (correct.Value)
100112
{
101113
await CheckNowCompleted(handler, check, userId, "UploadCheck");
102114
return;
@@ -120,7 +132,7 @@ private bool IsUniqueDataStale(TransferCheck check)
120132
check.CompletedUtc < expiry;
121133
}
122134

123-
private async Task<string> UploadData(string uniqueData)
135+
private string? UploadData(string uniqueData)
124136
{
125137
var filePath = Path.Combine(config.ChecksDataPath, Guid.NewGuid().ToString());
126138

@@ -129,7 +141,7 @@ private async Task<string> UploadData(string uniqueData)
129141
File.WriteAllText(filePath, uniqueData);
130142
var file = new TrackedFile(log, filePath, "checkData");
131143

132-
return await codexWrapper.OnCodex(node =>
144+
return codexWrapper.OnCodex(node =>
133145
{
134146
return node.UploadFile(file).Id;
135147
});
@@ -145,11 +157,11 @@ private async Task<string> UploadData(string uniqueData)
145157
}
146158
}
147159

148-
private async Task<Manifest?> GetManifest(string receivedCid)
160+
private Manifest? GetManifest(string receivedCid)
149161
{
150162
try
151163
{
152-
return await codexWrapper.OnCodex(node =>
164+
return codexWrapper.OnCodex(node =>
153165
{
154166
return node.DownloadManifestOnly(new ContentId(receivedCid)).Manifest;
155167
});
@@ -172,11 +184,11 @@ private bool IsManifestLengthCompatible(ICheckResponseHandler handler, TransferC
172184
manifestLength < (dataLength + 1);
173185
}
174186

175-
private async Task<bool> IsContentCorrect(ICheckResponseHandler handler, TransferCheck check, string receivedCid)
187+
private bool? IsContentCorrect(ICheckResponseHandler handler, TransferCheck check, string receivedCid)
176188
{
177189
try
178190
{
179-
var content = await codexWrapper.OnCodex(node =>
191+
var content = codexWrapper.OnCodex(node =>
180192
{
181193
var file = node.DownloadContent(new ContentId(receivedCid));
182194
if (file == null) return string.Empty;
@@ -190,6 +202,8 @@ private async Task<bool> IsContentCorrect(ICheckResponseHandler handler, Transfe
190202
}
191203
});
192204

205+
if (content == null) return null;
206+
193207
Log($"Checking content: content={content},check={check.UniqueData}");
194208
return content == check.UniqueData;
195209
}

Tools/BiblioTech/CodexChecking/CodexWrapper.cs

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,38 +21,72 @@ public CodexWrapper(ILog log, Configuration config)
2121

2222
var httpFactory = CreateHttpFactory();
2323
factory = new CodexNodeFactory(log, httpFactory, dataDir: config.DataPath);
24+
25+
Task.Run(CheckCodexNode);
2426
}
2527

26-
public async Task OnCodex(Action<ICodexNode> action)
28+
public T? OnCodex<T>(Func<ICodexNode, T> func) where T : class
2729
{
28-
await Task.Run(() =>
30+
lock (codexLock)
2931
{
30-
lock (codexLock)
31-
{
32-
action(Get());
33-
}
34-
});
32+
if (currentCodexNode == null) return null;
33+
return func(currentCodexNode);
34+
}
3535
}
3636

37-
public async Task<T> OnCodex<T>(Func<ICodexNode, T> func)
37+
private void CheckCodexNode()
3838
{
39-
return await Task<T>.Run(() =>
39+
Thread.Sleep(TimeSpan.FromSeconds(10.0));
40+
41+
while (true)
4042
{
4143
lock (codexLock)
4244
{
43-
return func(Get());
45+
var newNode = GetNewCodexNode();
46+
if (newNode != null && currentCodexNode == null) ShowConnectionRestored();
47+
if (newNode == null && currentCodexNode != null) ShowConnectionLost();
48+
currentCodexNode = newNode;
4449
}
45-
});
50+
51+
Thread.Sleep(TimeSpan.FromMinutes(15.0));
52+
}
4653
}
4754

48-
private ICodexNode Get()
55+
private ICodexNode? GetNewCodexNode()
4956
{
50-
if (currentCodexNode == null)
57+
try
5158
{
52-
currentCodexNode = CreateCodex();
59+
if (currentCodexNode != null)
60+
{
61+
try
62+
{
63+
// Current instance is responsive? Keep it.
64+
var info = currentCodexNode.GetDebugInfo();
65+
if (info != null && info.Version != null &&
66+
!string.IsNullOrEmpty(info.Version.Revision)) return currentCodexNode;
67+
}
68+
catch
69+
{
70+
}
71+
}
72+
73+
return CreateCodex();
5374
}
75+
catch (Exception ex)
76+
{
77+
log.Error("Exception when trying to check codex node: " + ex.Message);
78+
return null;
79+
}
80+
}
5481

55-
return currentCodexNode;
82+
private void ShowConnectionLost()
83+
{
84+
Program.AdminChecker.SendInAdminChannel("Codex node connection lost.");
85+
}
86+
87+
private void ShowConnectionRestored()
88+
{
89+
Program.AdminChecker.SendInAdminChannel("Codex node connection restored.");
5690
}
5791

5892
private ICodexNode CreateCodex()
@@ -76,7 +110,7 @@ private HttpFactory CreateHttpFactory()
76110
{
77111
if (string.IsNullOrEmpty(config.CodexEndpointAuth) || !config.CodexEndpointAuth.Contains(":"))
78112
{
79-
return new HttpFactory(log);
113+
return new HttpFactory(log, new SnappyTimeSet());
80114
}
81115

82116
var tokens = config.CodexEndpointAuth.Split(':');

Tools/BiblioTech/Commands/CheckResponseHandler.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ public async Task CouldNotDownloadCid()
2626
await context.Followup("Could not download the CID.");
2727
}
2828

29+
public async Task CodexUnavailable()
30+
{
31+
await context.Followup("Couldn't perform check: Our Codex node appears unavailable. Try again later?");
32+
}
33+
2934
public async Task GiveCidToUser(string cid)
3035
{
3136
await context.Followup(

0 commit comments

Comments
 (0)