aboutsummaryrefslogtreecommitdiff
path: root/plugins/ObjectCacheServer/src/ServerClusterConfig.cs
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/ObjectCacheServer/src/ServerClusterConfig.cs')
-rw-r--r--plugins/ObjectCacheServer/src/ServerClusterConfig.cs152
1 files changed, 152 insertions, 0 deletions
diff --git a/plugins/ObjectCacheServer/src/ServerClusterConfig.cs b/plugins/ObjectCacheServer/src/ServerClusterConfig.cs
new file mode 100644
index 0000000..8e098cd
--- /dev/null
+++ b/plugins/ObjectCacheServer/src/ServerClusterConfig.cs
@@ -0,0 +1,152 @@
+/*
+* Copyright (c) 2024 Vaughn Nugent
+*
+* Library: VNLib
+* Package: ObjectCacheServer
+* File: ServerClusterConfig.cs
+*
+* ServerClusterConfig.cs is part of ObjectCacheServer which is part of the larger
+* VNLib collection of libraries and utilities.
+*
+* ObjectCacheServer is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License as
+* published by the Free Software Foundation, either version 3 of the
+* License, or (at your option) any later version.
+*
+* ObjectCacheServer is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with this program. If not, see https://www.gnu.org/licenses/.
+*/
+
+using System;
+using System.Net;
+using System.Linq;
+using System.Text.Json;
+using System.Collections.Generic;
+
+using VNLib.Plugins;
+using VNLib.Utils.Logging;
+using VNLib.Utils.Extensions;
+using VNLib.Plugins.Extensions.Loading;
+using VNLib.Data.Caching.Extensions.Clustering;
+
+namespace VNLib.Data.Caching.ObjectCache.Server
+{
+ [ConfigurationName("cluster")]
+ internal sealed class ServerClusterConfig(PluginBase plugin, IConfigScope config)
+ {
+ public TimeSpan DiscoveryInterval { get; } = config.GetRequiredProperty("discovery_interval_sec", p => p.GetTimeSpan(TimeParseType.Seconds));
+
+ public TimeSpan EventQueuePurgeInterval { get; } = config.GetRequiredProperty("queue_purge_interval_sec", p => p.GetTimeSpan(TimeParseType.Seconds));
+
+ public int MaxQueueDepth { get; } = (int)config.GetRequiredProperty("max_queue_depth", p => p.GetUInt32());
+
+ public string? DiscoveryPath { get; } = config.GetValueOrDefault("discovery_path", p => p.GetString(), null);
+
+ public string ConnectPath { get; } = config.GetRequiredProperty("connect_path", p => p.GetString()!);
+
+ public string WellKnownPath { get; } = config.GetValueOrDefault("well_known_path", p => p.GetString()!, CacheConstants.DefaultWellKnownPath)
+ ?? CacheConstants.DefaultWellKnownPath;
+
+ public bool VerifyIp { get; } = config.GetRequiredProperty("verify_ip", p => p.GetBoolean());
+
+ /// <summary>
+ /// The maximum number of peer connections to allow
+ /// </summary>
+ public uint MaxPeerConnections { get; } = config.GetValueOrDefault("max_peers", p => p.GetUInt32(), 10u);
+
+ /// <summary>
+ /// The maxium number of concurrent client connections to allow
+ /// before rejecting new connections
+ /// </summary>
+ public uint MaxConcurrentConnections { get; } = config.GetValueOrDefault("max_concurrent_connections", p => p.GetUInt32(), 100u);
+
+ const string CacheConfigTemplate =
+@"
+Cluster Configuration:
+ Node Id: {id}
+ TlsEndabled: {tls}
+ Verify Ip: {vi}
+ Well-Known: {wk}
+ Cache Endpoint: {ep}
+ Discovery Endpoint: {dep}
+ Discovery Interval: {di}
+ Max Peer Connections: {mpc}
+ Max Queue Depth: {mqd}
+ Event Queue Purge Interval: {eqpi}
+";
+
+ internal CacheNodeConfiguration BuildNodeConfig()
+ {
+ CacheNodeConfiguration conf = new();
+
+ //Get the port of the primary webserver
+ int port;
+ bool usingTls;
+ {
+ //Get the port number of the first virtual host
+ JsonElement firstHost = plugin.HostConfig.GetProperty("virtual_hosts")
+ .EnumerateArray()
+ .First();
+
+ port = firstHost.GetProperty("interface")
+ .GetProperty("port")
+ .GetInt32();
+
+ //If the ssl element is present, ssl is enabled for the server
+ usingTls = firstHost.TryGetProperty("ssl", out _);
+ }
+ string hostname = Dns.GetHostName();
+
+ //Server id is just dns name for now
+ string nodeId = $"{hostname}:{port}";
+
+ Uri connectEp = BuildUri(usingTls, hostname, port, ConnectPath);
+ Uri? discoveryEp = null;
+
+
+ conf.WithCacheEndpoint(connectEp)
+ .WithNodeId(nodeId)
+ .WithTls(usingTls);
+
+ //Get the discovery path (optional)
+ if (!string.IsNullOrWhiteSpace(DiscoveryPath))
+ {
+ //Build the discovery endpoint, it must be an absolute uri
+ discoveryEp = BuildUri(usingTls, hostname, port, DiscoveryPath);
+ conf.EnableAdvertisment(discoveryEp);
+ }
+
+ //print the cluster configuration to the log
+ plugin.Log.Information(CacheConfigTemplate,
+ nodeId,
+ usingTls,
+ VerifyIp,
+ WellKnownPath,
+ connectEp,
+ discoveryEp,
+ DiscoveryInterval,
+ MaxPeerConnections,
+ MaxQueueDepth,
+ EventQueuePurgeInterval
+ );
+
+ return conf;
+ }
+
+ private static Uri BuildUri(bool tls, string host, int port, string path)
+ {
+ return new UriBuilder
+ {
+ Scheme = tls ? "https" : "http",
+ Host = host,
+ Port = port,
+ Path = path
+ }.Uri;
+ }
+ }
+}