Added potential implementation for scheduled jobs.

This commit is contained in:
Andrew Lalis 2024-08-04 19:06:24 -04:00
parent 82bfb474d8
commit 7a34d5bb34
2 changed files with 81 additions and 8 deletions

View File

@ -18,10 +18,13 @@ import core.sync.mutex;
import shared_utils.server_status; import shared_utils.server_status;
import shared_utils.discord; import shared_utils.discord;
import startup_requests;
const AGENT_KEY_HEADER = "X-Agent-Key"; const AGENT_KEY_HEADER = "X-Agent-Key";
const CLIENT_KEY_HEADER = "X-Client-Key"; const CLIENT_KEY_HEADER = "X-Client-Key";
__gshared ServerStatus[] serverStatuses; __gshared ServerStatus[] serverStatuses;
__gshared SysTime lastServerStatusTimestamp;
__gshared Mutex serversMutex; __gshared Mutex serversMutex;
__gshared ApiConfig config; __gshared ApiConfig config;
@ -38,6 +41,18 @@ void main() {
configureLoggingProvider(provider); configureLoggingProvider(provider);
serversMutex = new Mutex(); serversMutex = new Mutex();
lastServerStatusTimestamp = Clock.currTime();
// JobScheduler scheduler = JobScheduler.getDefault();
// scheduler.addJob(
// &removeOldStartupRequests,
// new FixedIntervalSchedule(minutes(5))
// );
// scheduler.addJob(
// &checkForOutOfDateServerStatus,
// new FixedIntervalSchedule(minutes(1))
// );
// scheduler.start();
PathHandler handler = new PathHandler(); PathHandler handler = new PathHandler();
handler.addMapping(Method.POST, "/api/servers", &postServerStatus); handler.addMapping(Method.POST, "/api/servers", &postServerStatus);
@ -66,11 +81,12 @@ void postServerStatus(ref HttpRequestContext ctx) {
serversMutex.lock(); serversMutex.lock();
scope(exit) serversMutex.unlock(); scope(exit) serversMutex.unlock();
serverStatuses = deserializeServerStatuses(jsonBody); serverStatuses = deserializeServerStatuses(jsonBody);
lastServerStatusTimestamp = Clock.currTime();
// Remove startup requests for any servers that are now online. // Remove startup requests for any servers that are now online.
foreach (server; serverStatuses) { foreach (server; serverStatuses) {
if (server.online && isStartupRequested(server.identifier)) { if (server.online && isStartupRequested(server.identifier)) {
std.file.remove("request_" ~ server.identifier ~ ".txt"); removeStartupRequest(server.identifier);
} }
} }
} }
@ -92,9 +108,7 @@ void requestServerStartup(ref HttpRequestContext ctx) {
scope(exit) serversMutex.unlock(); scope(exit) serversMutex.unlock();
foreach (server; serverStatuses) { foreach (server; serverStatuses) {
if (server.identifier == identifier) { if (server.identifier == identifier) {
File f = File("request_" ~ identifier ~ ".txt", "w"); createServerStartupRequest(server.identifier);
f.writeln(Clock.currTime().toISOExtString());
f.close();
sendDiscordMessage( sendDiscordMessage(
config.discordWebhookUrl, config.discordWebhookUrl,
format!"User requested to start server %s."(server.identifier) format!"User requested to start server %s."(server.identifier)
@ -118,10 +132,6 @@ void getServerRequests(ref HttpRequestContext ctx) {
ctx.response.writeBodyString(result.toJSON, "application/json"); ctx.response.writeBodyString(result.toJSON, "application/json");
} }
bool isStartupRequested(string id) {
return std.file.exists("request_" ~ id ~ ".txt");
}
void checkKey(ref HttpRequestContext ctx, string keyHeaderName, string expectedValue) { void checkKey(ref HttpRequestContext ctx, string keyHeaderName, string expectedValue) {
Optional!string key = ctx.request.headers.getFirst(keyHeaderName); Optional!string key = ctx.request.headers.getFirst(keyHeaderName);
if (!key || key.value != expectedValue) { if (!key || key.value != expectedValue) {
@ -140,3 +150,12 @@ ApiConfig readConfig() {
props["discordWebhookUrl"] props["discordWebhookUrl"]
); );
} }
void checkForOutOfDateServerStatus() {
Duration statusAge = Clock.currTime() - lastServerStatusTimestamp;
serversMutex.lock();
scope(exit) serversMutex.unlock();
if (statusAge > minutes(15) && serverStatuses.length > 0) {
serverStatuses = [];
}
}

View File

@ -0,0 +1,54 @@
module startup_requests;
import std.stdio;
import std.datetime;
import std.file;
import std.path;
import std.string;
void createServerStartupRequest(string serverIdentifier) {
File f = File(getRequestFile(serverIdentifier), "w");
f.writeln(Clock.currTime(UTC()).toISOExtString());
f.close();
}
bool isStartupRequested(string serverIdentifier) {
return exists(getRequestFile(serverIdentifier));
}
void removeStartupRequest(string serverIdentifier) {
string requestFile = getRequestFile(serverIdentifier);
if (exists(requestFile)) std.file.remove(requestFile);
}
void removeOldStartupRequests() {
foreach (string requestFile; findAllStartupRequests()) {
Duration age = getRequestAge(requestFile);
if (age > hours(1)) {
std.file.remove(requestFile);
}
}
}
private Duration getRequestAge(string requestFile) {
string text = readText(requestFile).strip();
SysTime timestamp = SysTime.fromISOExtString(text, UTC());
return Clock.currTime(UTC()) - timestamp;
}
private string[] findAllStartupRequests() {
string[] requestFiles;
foreach (DirEntry entry; dirEntries(getcwd(), SpanMode.shallow, false)) {
string filename = baseName(entry.name);
if (startsWith(filename, "request_") && endsWith(filename, ".txt")) {
requestFiles ~= entry.name;
}
}
return requestFiles;
}
private string getRequestFile(string identifier) {
return "request_" ~ identifier ~ ".txt";
}