He estado rascándome la cabeza con este por cerca de 2 semanas. Tengo un servidor Ubuntu 14.04 con rbenv instalado que ejecuta varios sitios web de Rails diferentes, algunos de ellos en versiones anteriores de Rails, algunos de ellos en la última versión.
Tengo 2 sitios web en particular que requieren una versión diferente de puma_worker_killer, 1 requiere 0.1.0 y el otro 0.1.1. Ambos sitios web usan Ruby 2.5.3.
Cuando inicio el servidor RAILS_ENV=dev3 bundle exec pumactl -F ./config/puma.rb start
, aparece el siguiente error en los registros y el sitio web se bloquea:
You have already activated puma_worker_killer 0.1.1, but your Gemfile requires puma_worker_killer 0.1.0. Prepending `bundle exec` to your command may solve this. (Gem::LoadError)
Al principio pensé que podría haber sido un problema con rbenv ya que tenía las gemas instaladas en ~ / .gem en lugar de en ~ / .rbenv, así que agregué todos los rubíes en ~ / .gem y los instalé nuevamente en el lugar correcto carpeta rbenv con bundle install
y sigo teniendo este mismo problema.
Ahora, en este punto, quiero aclarar que he realizado una extensa investigación sobre este tema en línea y sé que puedo hacer muchas cosas para resolverlo.
Sé que solo puedo cambiar la versión y bundle update puma_worker_killer
.
También sé que puedo eliminar la última versión haciendo gem uninstall puma_worker_killer
y eligiendo 0.1.1, pero esto significaría que las dependencias en el otro sitio web no se cumplirían.
He profundizado en el código fuente del bundler y puedo ver que es causado por la siguiente línea de código:
return if activated_spec.version == spec.version
Cuando se ejecuta en el contexto de bundler utilizando bundle exec
tanto el activated_spec
y el spec
partido, lo que significa que el siguiente código en ese método ( check_for_activated_spec!
) no se ejecuta. Por alguna razón, cuando se ejecuta el comando anterior para iniciar el servidor, activated_spec
(la gema activada) es la última versión (0.1.1) y no la que figura en el Gemfile (0.1.0), lo que significa que no regresa y arroja El error anterior.
También debo mencionar que también parece haber el mismo problema con get_process_mem, que es una de las dependencias de puma_worker_killer. Se queja de que ya está activando 0.2.5 pero mi Gemfile quiere 0.2.4:
You have already activated get_process_mem 0.2.5, but your Gemfile requires get_process_mem 0.2.4. Prepending `bundle exec` to your command may solve this. (Gem::LoadError)
Tengo entendido que el bundler debe cargar la versión listada en el Gemfile cuando se usa bundle exec
para contrarrestar este mismo problema de tener múltiples versiones de la misma gema.
Sé que también podría crear un conjunto de gemas por separado (que aparentemente se puede hacer con rbenv) que tiene diferentes versiones de puma_worker_killer en ellas y luego se ejecuta rbenv local 2.5.3-pwk0.1.0
o rbenv local 2.5.3-pwk0.1.1
depende de la versión que quiero, dentro del proyecto, pero parece excesivo para lo que quiero lograr.
A este ritmo, estoy tentado a actualizar todos los sitios web con la última versión de puma_worker_killer y get_process_mem y luego bloquearlos y eliminar todas las versiones anteriores del servidor, pero no creo que deba hacerlo.
¿Alguien sabe lo que está sucediendo aquí o si estoy haciendo algo notoriamente mal?
A continuación se muestra el código que uso para usar puma_worker_killer en mi configuración de puma.
before_fork do
require 'puma_worker_killer'
PumaWorkerKiller.config do |config|
config.ram = 1024 # mb
config.frequency = 5 # seconds
config.percent_usage = 0.98
config.rolling_restart_frequency = 12 * 3600 # 12 hours in seconds
end
PumaWorkerKiller.start
end
bundle update puma_worker_killer
¿no es así, ya que solo usará la versión más reciente de puma_worker_killer que está instalada en el servidorRespuestas:
Lo que está sucediendo aquí es que básicamente tienes varias versiones de la gema en tu sistema.
La mayoría de las veces no causó problemas porque
bundle exec
cargará dinámicamente las versiones requeridas para su aplicación.En algunos casos, las gemas tendrán archivos binarios incluidos. Tal caso
bundle exec
no ayudará porque solo puede tener una versión vinculada en un momento.Básicamente, si desea llamar al binario por alias, debe usar gemas separadas para cada aplicación.
Si desea mantener todas las gemas en un solo lugar, puede llamar directamente a archivos binarios.
En tu caso será:
La
_<version>_
construcción le permite especificar la versión del archivo binario que desea ejecutar.También puede crear su binario personalizado, como
fake_pumactl
dentro del proyecto, que verificaráGemfile.lock
y enviará automáticamente su llamada a la biblioteca y especificará la versión automáticamente. Otra forma es analizar la versión de gema por script de shell y poner este script en lugar de_<version>_
en su llamada.Aquí está el breve ejemplo.
puma_version
La variable se puede definir a partir del resultado de un comando bash que extraerá la versión de la gemaGemfile.lock
.fuente
RAILS_ENV=dev3 bundle exec pumactl _4.1.0_ -F ./config/puma.rb start
Ejecuto el siguiente comando: y comienza 3.7.0 en su lugar y no 4.1.0 (Version 3.7.0 (ruby 2.5.3-p105), codename: Snowy Sagebrush
)You can create your custom binary as well, like fake_pumactl inside the project which will check the Gemfile.lock and automatically proxy your call to the library and specify version automatically for you.
➜ app_root git:(develop) ✗ gem install puma -v 3.12.0 Building native extensions. This could take a while... Successfully installed puma-3.12.0 Done installing documentation for puma after 1 seconds 1 gem installed ➜ app_root git:(develop) ✗ pumactl _3.12.0_ -v 3.7.0
Necesito entender por qué, pero realmente has respondido mi pregunta, así que gracias y lo marcaré como respondidopumactl ${puma_version} -v
con${pumactl_path} -v
, debería funcionar dentro del directorio del proyecto dondepumactl_path
se definirá como la ruta a un binario dentro de forlder de gemas. Tal vezGemfile.lock
influya en el resultado de su comando porque contiene una versión anterior.