- VERSION 5.10.27

- feat(arquitectura): Consolidación de estabilidad y diagnóstico.
- refactor: Arquitectura de base de datos local y políticas de logs.
- arch(sqlite): Aislamiento total de las conexiones SQLite en SQL_Auth y SQL_Logs. Esto protege las operaciones de autenticación críticas de la alta carga de I/O generada por el subsistema de logs.
- feat(logs): Implementación de modo de almacenamiento flexible para logs (disco o en memoria), mejorando la capacidad de testing.
- refactor(logs): Se estandariza el límite de retención de registros a 10,000 para todas las tablas de logs, y se renombra la subrutina de limpieza a borraArribaDe10000Logs.
This commit is contained in:
jaguerrau
2025-10-29 05:25:49 -06:00
parent 4c7639f867
commit 9c9e2975e9
12 changed files with 1390 additions and 1374 deletions

View File

@@ -4,7 +4,7 @@ ModulesStructureVersion=1
Type=Class
Version=6.01
@EndOfDesignText@
'Class module
'Class module : HikariConnectionPool
'Author: Oliver Ackermann
'Created on: 2018/05/07
'Based on: https://github.com/AnywhereSoftware/B4J_Server/blob/master/src/anywheresoftware/b4j/object/ConnectionPool.java
@@ -27,7 +27,7 @@ End Sub
Public Sub Initialize
Dim properties As Map
properties.Initialize
'
'Frequently used
properties.Put("autocommit", "boolean")
properties.Put("connectiontimeout", "int")
@@ -73,7 +73,6 @@ Public Sub CreatePool2(driverClass As String, jdbcUrl As String, aUser As String
poolJO.RunMethod("setUsername", Array As Object(aUser))
poolJO.RunMethod("setPassword", Array As Object(aPassword))
If poolSize > 0 Then poolJO.RunMethod("setMaximumPoolSize", Array As Object(poolSize))
End Sub
Public Sub CreatePool3(options As Map)
@@ -85,7 +84,7 @@ End Sub
'that HikariConfig object.
Public Sub SetProperties(properties As Map)
' Valores óptimos por defecto para HikariCP (en milisegundos)
' Optimal default values for HikariCP (in milliseconds)
Private const DEFAULT_MAX_LIFE As Long = 1750000
Private const DEFAULT_CONN_TIMEOUT As Long = 30000
Private const DEFAULT_LEAK_THR As Long = 35000
@@ -93,112 +92,105 @@ Public Sub SetProperties(properties As Map)
Private const DEFAULT_MIN_IDLE As Int = 10
Private const DEFAULT_MAX_SIZE As Int = 10
Private const DEFAULT_KEEP_ALIVE_TIME As Long = 300000
Dim rawValue As String
Dim processedKeys As List
processedKeys.Initialize
Dim maxSize As Int ' Variable temporal para el tamaño máximo calculado
' --- INICIO: Procesamiento de Propiedades Críticas ---
' 1. MaxLifetime (Long) - Clave: maxlifetime
Dim maxSize As Int ' Temporary variable for the calculated maximum size
' 1. MaxLifetime (Long) - Key: maxlifetime
Dim maxLife As Long
If properties.ContainsKey("maxlifetime") Then
rawValue = properties.Get("maxlifetime").As(String).Trim
maxLife = rawValue
poolJO.RunMethod("setMaxLifetime", Array As Object(maxLife))
Log($"Ponemos (LONG, Config): MaxLifetime, ${maxLife}"$)
Log($"Ponemos MaxLifetime: ${maxLife}"$)
Else
maxLife = DEFAULT_MAX_LIFE
poolJO.RunMethod("setMaxLifetime", Array As Object(maxLife))
Log($"Ponemos (LONG, Default): MaxLifetime, ${DEFAULT_MAX_LIFE}"$)
End If
processedKeys.Add("maxlifetime")
MaxLifeConfig = maxLife ' <-- ALMACENAMIENTO CRÍTICO
' 2. ConnectionTimeout (Long) - Clave: connectiontimeout
MaxLifeConfig = maxLife ' Store the config value
' 2. ConnectionTimeout (Long) - Key: connectiontimeout
Dim connTimeout As Long
If properties.ContainsKey("connectiontimeout") Then
rawValue = properties.Get("connectiontimeout").As(String).Trim
connTimeout = rawValue
poolJO.RunMethod("setConnectionTimeout", Array As Object(connTimeout))
Log($"Ponemos (LONG, Config): ConnectionTimeout, ${connTimeout}"$)
Log($"Ponemos ConnectionTimeout: ${connTimeout}"$)
Else
connTimeout = DEFAULT_CONN_TIMEOUT
poolJO.RunMethod("setConnectionTimeout", Array As Object(connTimeout))
Log($"Ponemos (LONG, Default): ConnectionTimeout, ${DEFAULT_CONN_TIMEOUT}"$)
Log($"Ponemos ConnectionTimeout: ${DEFAULT_CONN_TIMEOUT}"$)
End If
processedKeys.Add("connectiontimeout")
ConnTimeoutConfig = connTimeout ' <-- ALMACENAMIENTO CRÍTICO
' 3. LeakDetectionThreshold (Long) - Clave: leakdetectionthreshold
ConnTimeoutConfig = connTimeout ' Store the config value
' 3. LeakDetectionThreshold (Long) - Key: leakdetectionthreshold
Dim leakThr As Long
If properties.ContainsKey("leakdetectionthreshold") Then
rawValue = properties.Get("leakdetectionthreshold").As(String).Trim
leakThr = rawValue
poolJO.RunMethod("setLeakDetectionThreshold", Array As Object(leakThr))
Log($"Ponemos (LONG, Config): LeakDetectionThreshold, ${leakThr}"$)
Log($"Ponemos LeakDetectionThreshold: ${leakThr}"$)
Else
leakThr = DEFAULT_LEAK_THR
poolJO.RunMethod("setLeakDetectionThreshold", Array As Object(leakThr))
Log($"Ponemos (LONG, Default): LeakDetectionThreshold, ${DEFAULT_LEAK_THR}"$)
End If
processedKeys.Add("leakdetectionthreshold")
LeakDetectionThresholdConfig = leakThr ' <-- ALMACENAMIENTO CRÍTICO
LeakDetectionThresholdConfig = leakThr ' Store the config value
' ********** LÓGICA DE FIXED POOL: MaximumPoolSize primero **********
' 4. MaximumPoolSize (Int) - Clave: maximumpoolsize
' 4. MaximumPoolSize (Int) - Key: maximumpoolsize
If properties.ContainsKey("maximumpoolsize") Then
rawValue = properties.Get("maximumpoolsize").As(String).Trim
maxSize = rawValue.As(Int)
poolJO.RunMethod("setMaximumPoolSize", Array As Object(maxSize))
Log($"Ponemos (INT, Config): MaximumPoolSize, ${maxSize}"$)
Log($"Ponemos MaximumPoolSize: ${maxSize}"$)
Else
maxSize = DEFAULT_MAX_SIZE
poolJO.RunMethod("setMaximumPoolSize", Array As Object(DEFAULT_MAX_SIZE))
Log($"Ponemos (INT, Default): MaximumPoolSize, ${DEFAULT_MAX_SIZE}"$)
Log($"Ponemos MaximumPoolSize: ${DEFAULT_MAX_SIZE}"$)
End If
processedKeys.Add("maximumpoolsize")
PoolSizeConfig = maxSize ' <-- ALMACENAMIENTO CRÍTICO
' 5. MinimumIdle (Int) - Clave: minimumidle
PoolSizeConfig = maxSize ' Store the config value
' 5. MinimumIdle (Int) - Key: minimumidle
Dim minIdleFinal As Int
If properties.ContainsKey("minimumidle") Then
rawValue = properties.Get("minimumidle").As(String).Trim
minIdleFinal = rawValue.As(Int)
poolJO.RunMethod("setMinimumIdle", Array As Object(minIdleFinal))
Log($"Ponemos (INT, Config): MinimumIdle, ${minIdleFinal}"$)
Log($"Ponemos MinimumIdle: ${minIdleFinal}"$)
Else
' APLICAMOS EL FIXED POOL AXIOM: MinimumIdle = MaximumPoolSize (maxSize)
' APPLY FIXED POOL AXIOM: MinimumIdle = MaximumPoolSize (maxSize)
minIdleFinal = maxSize
poolJO.RunMethod("setMinimumIdle", Array As Object(minIdleFinal))
Log($"Ponemos (INT, Fixed Default): MinimumIdle, ${minIdleFinal} (Igual a MaximumPoolSize)"$)
Log($"Ponemos MinimumIdle: ${minIdleFinal} (Igual a MaximumPoolSize)"$)
End If
processedKeys.Add("minimumidle")
MinIdleConfig = minIdleFinal ' <-- ALMACENAMIENTO CRÍTICO
' ********** FIN DE LA LÓGICA DE FIXED POOL **********
' 6. RegisterMbeans (Boolean) - Clave: registermbeans
MinIdleConfig = minIdleFinal ' Store the config value
' 6. RegisterMbeans (Boolean) - Key: registermbeans
If properties.ContainsKey("registermbeans") Then
Dim regMbeans As Boolean = properties.Get("registermbeans")
poolJO.RunMethod("setRegisterMbeans", Array As Object(regMbeans))
Log($"Ponemos (BOOL, Config): RegisterMbeans, ${regMbeans}"$)
Log($"Ponemos RegisterMbeans: ${regMbeans}"$)
Else
poolJO.RunMethod("setRegisterMbeans", Array As Object(DEFAULT_REG_MBEANS))
Log($"Ponemos (BOOL, Default): RegisterMbeans, ${DEFAULT_REG_MBEANS}"$)
Log($"Ponemos RegisterMbeans: ${DEFAULT_REG_MBEANS}"$)
End If
processedKeys.Add("registermbeans")
' 7. KeepaliveTime (Long) - Clave: keepalivetime
' 7. KeepaliveTime (Long) - Key: keepalivetime
Dim keepAlive As Long
If properties.ContainsKey("keepalivetime") Then
rawValue = properties.Get("keepalivetime").As(String).Trim
keepAlive = rawValue
' El valor mínimo aceptado es 30,000 ms [4].
' The minimum accepted value is 30,000 ms [4].
If keepAlive < 30000 Then keepAlive = 30000
poolJO.RunMethod("setKeepaliveTime", Array As Object(keepAlive))
@@ -206,13 +198,12 @@ Public Sub SetProperties(properties As Map)
Else
keepAlive = DEFAULT_KEEP_ALIVE_TIME
poolJO.RunMethod("setKeepaliveTime", Array As Object(keepAlive))
Log($"Ponemos (LONG, Default): KeepaliveTime, ${DEFAULT_KEEP_ALIVE_TIME} (50 minutos)"$)
Log($"Ponemos KeepaliveTime: ${DEFAULT_KEEP_ALIVE_TIME} (50 minutes)"$)
End If
processedKeys.Add("keepalivetime")
KeepAliveTimeConfig = keepAlive ' <-- ALMACENAMIENTO CRÍTICO
' --- INICIO: PROCESAMIENTO DE PROPIEDADES RESTANTES ---
' ... (El resto del código de procesamiento de propiedades restantes se mantiene igual)
KeepAliveTimeConfig = keepAlive ' Store the config value
' Process remaining properties
Dim intValue As Int
Dim booleanValue As Boolean
Dim variableType As String
@@ -238,9 +229,9 @@ Public Sub SetProperties(properties As Map)
Else
Log($"Connection pool property ${k} has unsupported variable type of ${variableType}"$)
End If
Log($"Ponemos (Restante): ${k}, ${properties.Get(k)}"$)
Log($"Ponemos (Remaining): ${k}, ${properties.Get(k)}"$)
Catch
Log($"Warning (Restante): Method: ${dynamicMethodName} not matched or type mismatch for property ${k}. Error: ${LastException.Message}"$)
Log($"Warning (Remaining): Method: ${dynamicMethodName} not matched or type mismatch for property ${k}. Error: ${LastException.Message}"$)
End Try
Else
Log($"Warning: Property ${k} not supported"$)
@@ -249,23 +240,19 @@ Public Sub SetProperties(properties As Map)
Next
End Sub
' // ---------------------------------------------------------------------------------------------------------------------------------------------------
' // NUEVA SUBRUTINA: Aplica propiedades específicas del Driver JDBC (Ej: MySQL caching)
' // Estas propiedades se aplican usando addDataSourceProperty, que no se soporta en SetProperties estándar.
' // ---------------------------------------------------------------------------------------------------------------------------------------------------
' Applies specific JDBC Driver properties (e.g., MySQL caching)
' These properties are applied using addDataSourceProperty, which is not supported in standard SetProperties.
Public Sub SetDriverProperties(properties As Map)
' properties es el mapa que RDCConnector.LoadDriverProperties extrae (ej: driver.mysql.*).
' properties is the map extracted by RDCConnector.LoadDriverProperties (e.g., driver.mysql.*).
Dim value As Object
For Each k As String In properties.Keys
value = properties.Get(k)
' CRÍTICO: Usar addDataSourceProperty para configurar el Driver, no el Pool.
' Use addDataSourceProperty to configure the Driver, not the Pool.
poolJO.RunMethod("addDataSourceProperty", Array As Object(k, value))
Log($"HikariCP: Driver Property [${k}] added with value: ${value}"$)
Next
End Sub
'Check if JDBC URL is supported
Public Sub SupportUrl(jdbcUrl As String) As Boolean
If jdbcUrl.StartsWith("jdbc:sqlite") Then
@@ -300,48 +287,47 @@ Public Sub ClosePool
End If
End Sub
' ** ADVERTENCIA: Esta subrutina traduce los nombres de métodos internos de HikariCP
' ** a las claves genéricas (ej. BusyConnections) que RDCConnector espera.
' ** CRÍTICO: Ahora incluye la CONFIGURACIÓN ESTÁTICA guardada en las variables de clase.
' WARNING: This subroutine translates internal HikariCP method names
' to the generic keys (e.g., BusyConnections) that RDCConnector expects.
' It now includes the STATIC CONFIGURATION saved in the class variables.
Public Sub GetStats As Map
Dim stats As Map
stats.Initialize
' 1. AGREGAR PROPIEDADES ESTÁTICAS (CONFIGURACIÓN ALMACENADA)
' 1. ADD STATIC PROPERTIES (STORED CONFIGURATION)
stats.Put("MaxPoolSize", PoolSizeConfig)
stats.Put("MinPoolSize", MinIdleConfig)
stats.Put("MaxLifetime", MaxLifeConfig)
stats.Put("ConnectionTimeout", ConnTimeoutConfig)
stats.Put("LeakDetectionThreshold", LeakDetectionThresholdConfig)
stats.Put("KeepaliveTime", KeepAliveTimeConfig)
' Nota: Aquí puedes agregar las propiedades estáticas adicionales que sean relevantes.
' 2. OBTENER MÉTRICAS DE TIEMPO DE EJECUCIÓN (JMX/MBean)
' Note: You can add other relevant static properties here.
' 2. GET RUNTIME METRICS (JMX/MBean)
If poolJO.IsInitialized Then
Try
Dim poolMBean As JavaObject = poolJO.RunMethod("getHikariPoolMXBean", Null)
Dim busyConn As Object = poolMBean.RunMethod("getActiveConnections", Null)
stats.Put("BusyConnections", busyConn)
Dim idleConn As Object = poolMBean.RunMethod("getIdleConnections", Null)
stats.Put("IdleConnections", idleConn)
Dim activeCount As Int = busyConn
Dim idleCount As Int = idleConn
stats.Put("TotalConnections", activeCount + idleCount)
Dim awaitingConn As Object = poolMBean.RunMethod("getThreadsAwaitingConnection", Null)
stats.Put("ThreadsAwaitingConnection", awaitingConn)
Catch
Dim ErrorMsg As String = "HikariCP.GetStats: Error al obtener métricas dinámicas del MBean: " & LastException.Message
Dim ErrorMsg As String = "HikariCP.GetStats: Error getting dynamic metrics from MBean: " & LastException.Message
Log(ErrorMsg)
stats.Put("Error_Runtime", ErrorMsg)
End Try
Else
stats.Put("Error", "Pool JO no inicializado")
stats.Put("Error", "Pool JO not initialized")
End If
Return stats
End Sub
End Sub