Refine code changes

* Refine code changes from #2608 based on memory allocation and usage
This commit is contained in:
abraunegg 2024-04-13 08:08:19 +10:00
parent 2bb82f718f
commit ec933af290
8 changed files with 131 additions and 83 deletions

View file

@ -30,6 +30,13 @@ class ClientSideFiltering {
this.appConfig = appConfig;
}
~this() {
object.destroy(appConfig);
object.destroy(paths);
object.destroy(fileMask);
object.destroy(directoryMask);
}
// Initialise the required items
bool initialise() {
// Log what is being done

View file

@ -682,11 +682,21 @@ class ApplicationConfig {
}
auto file = File(filename, "r");
scope(exit) file.close();
scope(failure) file.close();
string lineBuffer;
scope(exit) {
file.close();
object.destroy(file);
object.destroy(lineBuffer);
}
scope(failure) {
file.close();
object.destroy(file);
object.destroy(lineBuffer);
}
foreach (line; file.byLine()) {
string lineBuffer = stripLeft(line).to!string;
lineBuffer = stripLeft(line).to!string;
if (lineBuffer.empty || lineBuffer[0] == ';' || lineBuffer[0] == '#') continue;
auto c = lineBuffer.matchFirst(configRegex);
if (c.empty) {

View file

@ -176,55 +176,62 @@ class CurlResponse {
class CurlEngine {
__gshared CurlEngine[] curlEnginePool;
__gshared static CurlEngine[] curlEnginePool; // __gshared is used for thread-shared static variables
HTTP http;
bool keepAlive;
ulong dnsTimeout;
CurlResponse response;
File uploadFile;
static CurlEngine get() {
synchronized(CurlEngine.classinfo) {
if (curlEnginePool.empty) {
return new CurlEngine;
} else {
CurlEngine curlEngine = curlEnginePool[$-1];
curlEnginePool.popBack();
return curlEngine;
}
}
}
static CurlEngine getCurlInstance() {
synchronized (CurlEngine.classinfo) {
if (curlEnginePool.empty) {
return new CurlEngine; // Constructs a new CurlEngine with a fresh HTTP instance
} else {
CurlEngine curlEngine = curlEnginePool[$ - 1];
curlEnginePool = curlEnginePool[0 .. $ - 1];
return curlEngine;
}
}
}
static releaseAll() {
synchronized(CurlEngine.classinfo) {
foreach(curlEngine; curlEnginePool) {
curlEngine.shutdown();
static void releaseAll() {
synchronized (CurlEngine.classinfo) {
foreach (CurlEngine curlEngine; curlEnginePool) {
curlEngine.cleanUp(); // Cleanup instance by resetting values
curlEngine.shutdown(); // Assume proper cleanup of any resources used by HTTP
object.destroy(curlEngine);
}
curlEnginePool = null;
}
}
}
curlEnginePool.length = 0;
}
// Cleanup curlEnginePool
object.destroy(curlEnginePool);
}
void release() {
cleanUp();
synchronized(CurlEngine.classinfo) {
curlEnginePool ~= this;
}
}
this() {
http = HTTP(); // Directly initializes HTTP using its default constructor
response = null; // Initialize as null
}
HTTP http;
bool keepAlive;
ulong dnsTimeout;
CurlResponse response;
File uploadFile;
this() {
http = HTTP();
response = null;
}
~this() {
object.destroy(http);
object.destroy(response);
~this() {
// The destructor should only clean up resources owned directly by this instance
// Avoid modifying or destroying shared/static resources here
if (uploadFile.isOpen())
uploadFile.close();
}
uploadFile.close();
// Cleanup curlEnginePool
object.destroy(curlEnginePool);
}
void release() {
cleanUp();
synchronized (CurlEngine.classinfo) {
curlEnginePool ~= this;
}
}
void initialise(ulong dnsTimeout, ulong connectTimeout, ulong dataTimeout, ulong operationTimeout, int maxRedirects, bool httpsDebug, string userAgent, bool httpProtocol, ulong userRateLimit, ulong protocolVersion, bool keepAlive=true) {
// Setting this to false ensures that when we close the curl instance, any open sockets are closed - which we need to do when running
// multiple threads and API instances at the same time otherwise we run out of local files | sockets pretty quickly

View file

@ -100,7 +100,8 @@ class LogBuffer {
// Use dnotify's functionality for GUI notifications, if GUI notifications is enabled
version(Notifications) {
try {
auto n = new Notification("Log Notification", message, "IGNORED");
auto n = new Notification("OneDrive Client for Linux", message, "IGNORED");
//n.timeout = 5;
n.show();
} catch (NotificationError e) {
sendGUINotification = false;

View file

@ -1123,12 +1123,6 @@ void performStandardExitProcess(string scopeCaller = null) {
object.destroy(oneDriveWebhook);
}
// Shutdown the sync engine
if (syncEngineInstance !is null) {
addLogEntry("Shutdown Sync Engine instance", ["debug"]);
object.destroy(syncEngineInstance);
}
// Shutdown the client side filtering objects
if (selectiveSync !is null) {
addLogEntry("Shutdown Client Side Filtering instance", ["debug"]);
@ -1151,6 +1145,12 @@ void performStandardExitProcess(string scopeCaller = null) {
object.destroy(filesystemMonitor);
}
// Shutdown the sync engine
if (syncEngineInstance !is null) {
addLogEntry("Shutdown Sync Engine instance", ["debug"]);
object.destroy(syncEngineInstance);
}
// Shutdown the database
if (itemDB !is null) {
addLogEntry("Shutdown Database instance", ["debug"]);

View file

@ -113,13 +113,17 @@ class OneDriveApi {
// Subscriptions
subscriptionUrl = appConfig.globalGraphEndpoint ~ "/v1.0/subscriptions";
}
~this() {
object.destroy(curlEngine);
}
// Initialise the OneDrive API class
bool initialise(bool keepAlive=true) {
// Initialise the curl engine
this.keepAlive = keepAlive;
if (curlEngine is null) {
curlEngine = CurlEngine.get();
curlEngine = CurlEngine.getCurlInstance();
curlEngine.initialise(appConfig.getValueLong("dns_timeout"), appConfig.getValueLong("connect_timeout"), appConfig.getValueLong("data_timeout"), appConfig.getValueLong("operation_timeout"), appConfig.defaultMaxRedirects, appConfig.getValueBool("debug_https"), appConfig.getValueString("user_agent"), appConfig.getValueBool("force_http_11"), appConfig.getValueLong("rate_limit"), appConfig.getValueLong("ip_protocol_version"), keepAlive);
}

View file

@ -298,6 +298,13 @@ class SyncEngine {
}
}
~this() {
processPool = null;
addLogEntry("processPool = null");
object.destroy(oneDriveApiInstance);
addLogEntry("object.destroy(oneDriveApiInstance)");
}
// Initialise the Sync Engine class
bool initialise() {
@ -519,7 +526,7 @@ class SyncEngine {
addLogEntry("Perform a Full Scan True-Up: " ~ to!string(appConfig.fullScanTrueUpRequired), ["debug"]);
// Fetch the API response of /delta to track changes that were performed online
fetchOneDriveDeltaAPIResponse(null, null, null);
fetchOneDriveDeltaAPIResponse();
// Process any download activities or cleanup actions
processDownloadActivities();

View file

@ -201,42 +201,54 @@ Regex!char wild2regex(const(char)[] pattern) {
return regex(str, "i");
}
// Test Internet access to Microsoft OneDrive
// Test Internet access to Microsoft OneDrive using a simple HTTP HEAD request
bool testInternetReachability(ApplicationConfig appConfig) {
CurlEngine curlEngine;
bool result = false;
auto http = HTTP();
http.url = "https://login.microsoftonline.com";
// Configure timeouts based on application configuration
http.dnsTimeout = dur!"seconds"(appConfig.getValueLong("dns_timeout"));
http.connectTimeout = dur!"seconds"(appConfig.getValueLong("connect_timeout"));
http.dataTimeout = dur!"seconds"(appConfig.getValueLong("data_timeout"));
http.operationTimeout = dur!"seconds"(appConfig.getValueLong("operation_timeout"));
// Set IP protocol version
http.handle.set(CurlOption.ipresolve, appConfig.getValueLong("ip_protocol_version"));
// Set HTTP method to HEAD for minimal data transfer
http.method = HTTP.Method.head;
// Execute the request and handle exceptions
try {
// Use preconfigured object with all the correct http values assigned
curlEngine = CurlEngine.get();
curlEngine.initialise(appConfig.getValueLong("dns_timeout"), appConfig.getValueLong("connect_timeout"), appConfig.getValueLong("data_timeout"), appConfig.getValueLong("operation_timeout"), appConfig.defaultMaxRedirects, appConfig.getValueBool("debug_https"), appConfig.getValueString("user_agent"), appConfig.getValueBool("force_http_11"), appConfig.getValueLong("rate_limit"), appConfig.getValueLong("ip_protocol_version"));
addLogEntry("Attempting to contact Microsoft OneDrive Login Service");
http.perform();
// Configure the remaining items required
// URL to use
// HTTP connection test method
// Check response for HTTP status code
if (http.statusLine.code >= 200 && http.statusLine.code < 400) {
addLogEntry("Successfully reached Microsoft OneDrive Login Service");
} else {
addLogEntry("Failed to reach Microsoft OneDrive Login Service. HTTP status code: " ~ to!string(http.statusLine.code));
throw new Exception("HTTP Request Failed with Status Code: " ~ to!string(http.statusLine.code));
}
curlEngine.connect(HTTP.Method.head, "https://login.microsoftonline.com");
addLogEntry("Attempting to contact Microsoft OneDrive Login Service", ["debug"]);
curlEngine.http.perform();
addLogEntry("Shutting down HTTP engine as successfully reached OneDrive Login Service", ["debug"]);
result = true;
http.shutdown();
return true;
} catch (SocketException e) {
addLogEntry("HTTP Socket Issue", ["debug"]);
addLogEntry("Cannot connect to Microsoft OneDrive Login Service - Socket Issue");
addLogEntry("Cannot connect to Microsoft OneDrive Service - Socket Issue: " ~ e.msg);
displayOneDriveErrorMessage(e.msg, getFunctionName!({}));
http.shutdown();
return false;
} catch (CurlException e) {
addLogEntry("No Network Connection", ["debug"]);
addLogEntry("Cannot connect to Microsoft OneDrive Login Service - Network Connection Issue");
addLogEntry("Cannot connect to Microsoft OneDrive Service - Network Connection Issue: " ~ e.msg);
displayOneDriveErrorMessage(e.msg, getFunctionName!({}));
}
// Shutdown engine
curlEngine.http.shutdown();
curlEngine.releaseAll();
object.destroy(curlEngine);
curlEngine = null;
// Return test result
return result;
http.shutdown();
return false;
} catch (Exception e) {
addLogEntry("Unexpected error occurred: " ~ e.toString());
displayOneDriveErrorMessage(e.toString(), getFunctionName!({}));
http.shutdown();
return false;
}
}
// Retry Internet access test to Microsoft OneDrive