bug_bunny 3.1.3 → 3.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4aab7949b09bfbf861d4a9ff736bc3bef832fdb3c8a302924544783bdbc9e1bf
4
- data.tar.gz: 12b73641a812ec4ce72d2a5ad8992a1f2b91c4b0b11ce181aac02fe3a4912751
3
+ metadata.gz: 28bb35f1140309e9527c44f108cba3b58b85aae52c7253d17f35f7b35e248661
4
+ data.tar.gz: f3b30d3b77b1c242c3e8c8fc9576d8143b2587b60da83a0d633604eaca464ebd
5
5
  SHA512:
6
- metadata.gz: 2f4475f1754c1de91be6576d4fabb23d025b1f3735d4d76d3123415e71b907d2bfc307dd8e8f4a921ad5a11b2524cd85a1ee17ea3fb1d42f6e15c62ddef01425
7
- data.tar.gz: c3973288d2d394121491ffb3c7fa809b8841c9fdc3fc87486fb807b62b6f948e48298fd9f4b696132c9b86d448dad82bd4cfa909c39384efc2ab1b7729c15f31
6
+ metadata.gz: a069a81c26762bedc55cb8c0be70ac6ff2154d70d4b54f10d7650ddc27160cf400c4c8b680e50e0fd3529f39447ccfcb83864ae7d99396ee7ce62ef5d84da6fd
7
+ data.tar.gz: d8e5130f3d6830023f85516a2dec1db036c49cc0963af8f92255987c32b6e721e2785ed54c4d2b9ac94931c5b3e1073c1b1a549265aabb39839f0b95348deaaa
data/CHANGELOG.md CHANGED
@@ -1,4 +1,15 @@
1
1
  # Changelog
2
+ ## [3.1.4] - 2026-02-21
3
+
4
+ ### 🚀 Cloud Native & Infrastructure Features
5
+ * **Docker Swarm / Kubernetes Health Checks:** Introduced native support for external orchestrator health checks using the **Touchfile** pattern.
6
+ * Added `config.health_check_file` to the global configuration.
7
+ * The `Consumer`'s internal heartbeat now automatically updates the modification time (`touch`) of the specified file upon successful validation of the RabbitMQ connection and queue existence.
8
+ * Fails gracefully without interrupting the consumer if file system permissions are restricted.
9
+
10
+ ### 📖 Documentation
11
+ * **Production Guide Expansion:** Added a comprehensive "Health Checks en Docker Swarm / Kubernetes" section to the README. Includes detailed `docker-compose.yml` examples demonstrating best practices for integrating the touchfile pattern, specifically highlighting the critical use of `start_period` to accommodate Rails boot times.
12
+
2
13
  ## [3.1.3] - 2026-02-19
3
14
 
4
15
  ### 🏗️ Architectural Refactoring (Middleware Standardization)
data/README.md CHANGED
@@ -76,11 +76,14 @@ BugBunny.configure do |config|
76
76
  config.rpc_timeout = 10 # Segundos máx para esperar respuesta (Síncrono)
77
77
  config.network_recovery_interval = 5 # Reintento de conexión
78
78
 
79
- # 3. Logging
79
+ # 3. Health Checks (Opcional, para Docker Swarm / K8s)
80
+ config.health_check_file = '/tmp/bug_bunny_health'
81
+
82
+ # 4. Logging
80
83
  config.logger = Rails.logger
81
84
  end
82
85
 
83
- # 4. Connection Pool (CRÍTICO para concurrencia)
86
+ # 5. Connection Pool (CRÍTICO para concurrencia)
84
87
  # Define un pool global para compartir conexiones entre hilos
85
88
  BUG_BUNNY_POOL = ConnectionPool.new(size: ENV.fetch('RAILS_MAX_THREADS', 5).to_i, timeout: 5) do
86
89
  BugBunny.create_connection
@@ -377,6 +380,35 @@ Para máxima velocidad, BugBunny usa `amq.rabbitmq.reply-to`.
377
380
  ### Seguridad
378
381
  El Router incluye protecciones contra **Remote Code Execution (RCE)**. Verifica estrictamente que la clase instanciada herede de `BugBunny::Controller` antes de ejecutarla, impidiendo la inyección de clases arbitrarias de Ruby vía el header `type`.
379
382
 
383
+ ### Health Checks en Docker Swarm / Kubernetes
384
+ Dado que un Worker se ejecuta en segundo plano sin exponer un servidor web tradicional, orquestadores como Docker Swarm o Kubernetes no pueden usar un endpoint HTTP para verificar si el proceso está saludable.
385
+
386
+ BugBunny implementa el patrón **Touchfile**. Puedes configurar la gema para que actualice la fecha de modificación de un archivo temporal en cada latido exitoso (heartbeat) hacia RabbitMQ.
387
+
388
+ **1. Configurar la gema:**
389
+ ```ruby
390
+ # config/initializers/bug_bunny.rb
391
+ BugBunny.configure do |config|
392
+ # Actualizará la fecha de este archivo si la conexión a la cola está sana
393
+ config.health_check_file = '/tmp/bug_bunny_health'
394
+ end
395
+ ```
396
+
397
+ **2. Configurar el Orquestador (Ejemplo docker-compose.yml):**
398
+ Con esta configuración, Docker Swarm verificará que el archivo haya sido modificado (tocado) en los últimos 15 segundos. Si el worker se bloquea o pierde la conexión de manera irrecuperable, Docker reiniciará el contenedor automáticamente.
399
+
400
+ ```yaml
401
+ services:
402
+ worker:
403
+ image: my_rails_app
404
+ command: bundle exec rake bug_bunny:work
405
+ healthcheck:
406
+ test: ["CMD-SHELL", "test $$(expr $$(date +%s) - $$(stat -c %Y /tmp/bug_bunny_health)) -lt 15 || exit 1"]
407
+ interval: 10s
408
+ timeout: 5s
409
+ retries: 3
410
+ ```
411
+
380
412
  ---
381
413
 
382
414
  ## 📄 Licencia
@@ -11,6 +11,7 @@ module BugBunny
11
11
  # BugBunny.configure do |config|
12
12
  # config.host = '127.0.0.1'
13
13
  # config.exchange_options = { durable: true, auto_delete: false }
14
+ # config.health_check_file = '/tmp/bug_bunny_health'
14
15
  # end
15
16
  class Configuration
16
17
  # @return [String] Host o IP del servidor RabbitMQ (ej: 'localhost').
@@ -64,6 +65,12 @@ module BugBunny
64
65
  # @return [Integer] Intervalo en segundos para verificar la salud de la cola.
65
66
  attr_accessor :health_check_interval
66
67
 
68
+ # @return [String, nil] Ruta del archivo que se actualizará (touch) en cada health check exitoso.
69
+ # Ideal para sondas (probes) de orquestadores como Docker Swarm o Kubernetes.
70
+ # Si es `nil`, la funcionalidad de touchfile se desactiva.
71
+ # @example '/tmp/bug_bunny_health'
72
+ attr_accessor :health_check_file
73
+
67
74
  # @return [String] Namespace base donde se buscarán los controladores (default: 'Rabbit::Controllers').
68
75
  attr_accessor :controller_namespace
69
76
 
@@ -108,6 +115,9 @@ module BugBunny
108
115
  @rpc_timeout = 10
109
116
  @health_check_interval = 60
110
117
 
118
+ # Desactivado por defecto. El usuario debe especificar una ruta explícita para habilitarlo.
119
+ @health_check_file = nil
120
+
111
121
  # Configuración por defecto para mantener compatibilidad
112
122
  @controller_namespace = 'Rabbit::Controllers'
113
123
 
@@ -1,10 +1,12 @@
1
- # lib/bug_bunny/consumer.rb
1
+ # frozen_string_literal: true
2
+
2
3
  require 'active_support/core_ext/string/inflections'
3
4
  require 'concurrent'
4
5
  require 'json'
5
6
  require 'uri'
6
7
  require 'cgi'
7
8
  require 'rack/utils' # Necesario para parse_nested_query
9
+ require 'fileutils' # Necesario para el touchfile del health check
8
10
 
9
11
  module BugBunny
10
12
  # Consumidor de mensajes AMQP que actúa como un Router RESTful.
@@ -253,14 +255,40 @@ module BugBunny
253
255
  # Tarea de fondo (Heartbeat lógico) para verificar la salud del canal.
254
256
  # Si la cola desaparece o la conexión se cierra, fuerza una reconexión.
255
257
  #
258
+ # Adicionalmente, si `health_check_file` está configurado, actualiza la
259
+ # fecha de modificación (touch) de dicho archivo para notificar a orquestadores
260
+ # externos (como Docker Swarm o Kubernetes) que el proceso está saludable.
261
+ #
256
262
  # @param q_name [String] Nombre de la cola a monitorear.
263
+ # @return [void]
257
264
  def start_health_check(q_name)
265
+ file_path = BugBunny.configuration.health_check_file
266
+
267
+ # Toque inicial para indicar al orquestador que el worker arrancó correctamente
268
+ touch_health_file(file_path) if file_path
269
+
258
270
  Concurrent::TimerTask.new(execution_interval: BugBunny.configuration.health_check_interval) do
271
+ # 1. Verificamos la salud de RabbitMQ (si falla, levanta un error y corta la ejecución del bloque)
259
272
  session.channel.queue_declare(q_name, passive: true)
260
- rescue StandardError
261
- BugBunny.configuration.logger.warn("[BugBunny::Consumer] ⚠️ Queue check failed. Reconnecting session...")
273
+
274
+ # 2. Si llegamos aquí, RabbitMQ y la cola están vivos. Avisamos al orquestador actualizando el archivo.
275
+ touch_health_file(file_path) if file_path
276
+ rescue StandardError => e
277
+ BugBunny.configuration.logger.warn("[BugBunny::Consumer] ⚠️ Queue check failed: #{e.message}. Reconnecting session...")
262
278
  session.close
263
279
  end.execute
264
280
  end
281
+
282
+ # Actualiza la fecha de modificación del archivo de health check (touchfile).
283
+ # Se utiliza un `rescue` genérico para no interrumpir el flujo principal del worker
284
+ # si el contenedor de Docker tiene problemas de permisos sobre la carpeta temporal.
285
+ #
286
+ # @param file_path [String] Ruta absoluta del archivo a tocar.
287
+ # @return [void]
288
+ def touch_health_file(file_path)
289
+ FileUtils.touch(file_path)
290
+ rescue StandardError => e
291
+ BugBunny.configuration.logger.error("[BugBunny::Consumer] ⚠️ Cannot touch health check file '#{file_path}': #{e.message}")
292
+ end
265
293
  end
266
294
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BugBunny
4
- VERSION = "3.1.3"
4
+ VERSION = "3.1.4"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bug_bunny
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.3
4
+ version: 3.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - gabix
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-02-19 00:00:00.000000000 Z
11
+ date: 2026-02-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bunny