neecsitamos poner ademas
bd=nro de base de redis
usuario=
passs=
hicimos una prueba poniendo algo como esto
host = “keystore-ejemplo.unc.edu.ar”
port = “6379?baseauth[user]=default&auth[pass]=***********&database=16”
Al menos que veamos que otras opciones se pueden pasar.
Esto de Rest Hooks se utiliza en src/SIU/Guarani/RestHooks/RestHookSanaviron.php para la comunicación en SQ, en la función getRestMessenger vas a ver parte de la configuración que se le pasa a la clase RestMessenger.php. Podes ver las funciones del estilo public function setXxx (ej: public function setRedisConfig($host)), quizás encuentres alguna donde se puedan pasar los parámetros de conexión a la DB.
Nosotros usamos el esquema rest_hooks dentro de la DB de Guaraní, en el mismo se crean solo tres tablas: messages, phinxlog y requests. Eso se configura en src/SIU/Guarani/RestHooks/RestHookSanaviron.php función getRestMessenger.
Muchas Gracias Leonel por la información!
Efectivamente logramos hacer funcionar el RestHook mediante el uso de un Redis fuera del nodo de Guarani. Como nos dijiste lo logramos haciendo modificaciones a la función getRestMessenger del archivo src/SIU/Guarani/RestHooks/RestHookSanaviron.php.
A continuación dejo la configuración de esa función para los que la deseen:
public static function getRestMessenger()
{
if (! isset(self::$rhlib)) {
$lib = new RestMessenger();
$lib->setMessageEncoding('iso-8859-1');
$restHooksIni = static::getConfigRestHooks();
$redisConf = $restHooksIni['redis_config'];
//Modificacion para recibir User,Password y BD
//Construccion de URI Redis
$redisServer = "redis://";
if (!empty($redisConf['user']) && !empty($redisConf['password'])) {
$redisServer .= $redisConf['user'] . ":" . $redisConf['password'] . "@";
} elseif (!empty($redisConf['password'])) {
// Si no hay user, pero si password (forma comun en Redis)
$redisServer .= ":" . $redisConf['password'] . "@";
}
$redisServer .= $redisConf['host'] . ":" . $redisConf['port'];
if (isset($redisConf['database'])) {
$redisServer .= "/" . $redisConf['database'];
}
if (isset($restHooksIni['resthooks_activo']) && $restHooksIni['resthooks_activo'] == 1) {
$lib->setMode(RestMessenger::MODE_ENQUEUE);
$lib->setInitializerMethod("\\SIU\\Guarani\\RestHooks\\RestHookSanaviron::getRestMessenger");
$lib->setMaxRetries(static::MAX_RETRIES);
$lib->setConfig($redisServer);
} else {
// si no esta activo resthook se envia directamente sin reintentos
$lib->setConfig($redisServer);
$lib->setMode(RestMessenger::MODE_DIRECT);
}
$defBase = static::getConfigDB();
$backend = new Postgres([
'dbname' => $defBase['base'],
'host' => $defBase['profile'],
'port' => $defBase['puerto'],
'username' => $defBase['usuario'],
'password' => $defBase['clave'],
'schema' => static::SCHEMA_DB
]);
$lib->setBackend($backend);
$apiRestConf = static::getConfigApiRest();
$topic = $lib->createTopic('post_suscripciones_novedades');
$lib->addTopic($topic);
$listener = self::listenerPostSuscripcionesNovedades($topic, $apiRestConf);
$lib->addListener($listener);
$topic = $lib->createTopic('post_servicios');
$lib->addTopic($topic);
$listener = self::listenerPostServicios($topic, $apiRestConf);
$lib->addListener($listener);
$topic = $lib->createTopic('post_solicitudes_consumos_externos');
$lib->addTopic($topic);
$listener = self::listenerPostSolicitudesConsumosExternos($topic, $apiRestConf);
$lib->addListener($listener);
$lib->logToFile(static::getRestLogDirectory()."/rest-hooks.log");
self::$rhlib = $lib;
}
return self::$rhlib;
}
El cambio mas significativo es en la variable redisServer para lograr armar la conexion con el servidor Redis de la forma:
Con esta configuracion se podia iniciar sesion y navegar correctamente. El problema surgia en ciertos tramites, arrojaba error y no se realizaba el tramite, por ejemplo en el tramite “Actualizar Tramites de Certificacion”, al intengar cambiar el estado de un egresado, arrojaba el siguiente error:
Luego de probar diferentes cosas dimos con la solucion para este problema y entendimos el por que del mismo.
El problema consistia basicamente en que si dos peticiones para la misma sesion a redis llegaban en simultaneo o muy juntas, se pisaban y se perdian datos, en este caso vemos que el error dice “no se encuentra la lista de efs activos”. La solucion fue la siguiente:
Agregar un manejador de sesiones redis en toba:
En la ruta: /mnt/guarani/gestion/vendor/siu-toba/framework/php/nucleo/lib/session_handlers
Esto por que notamos que existen clases para files y memcached, pero no para redis en cuestion.
La otra parte de la solucion, que soluciona especificamente el problema de perdida de informacion por peticiones simultaneas o muy juntas, consiste en agregar tambien en el php.ini: redis.session.locking_enabled = 1 redis.session.lock_wait_time = 1000 redis.session.lock_retries = -1
Esto basicamente lo que hace es que si una request usa una sesion, esa sesion se bloquea hasta que termina la operacion y si otra request intenta usar tambien esa sesion, al estar bloqueada, esperara el tiempo seteado (seguira intentandola usar, por eso el -1 el lock_retries), si pasado ese segundo no se libera el lock y la sesion sigue bloqueada, ahi dejaria de intentar.
Con estas configuraciones logramos que el error dejara de aparecer. Si bien fue realizado en un entorno de laboratorio y aun falta seguir testeando, consideramos que es un gran avance ya que el error dejo de aparecer y nos parecio bien compartirlo en la comunidad.
Actualizo! No es necesario realizar el punto 1 (Agregar un manejador de sesiones redis en toba).
Se probo eliminando este manejador y solo dejar la configuarcion del punto 2 (configuracion del php.ini) y sigue funcionando correctamente.