Ich kratzte mir seit fast 2 Wochen am Kopf. Ich habe einen Ubuntu 14.04-Server mit rbenv installiert, auf dem verschiedene Rails-Websites ausgeführt werden, einige davon auf älteren Versionen von Rails, einige auf der neuesten Version.
Ich habe insbesondere 2 Websites, für die beide eine andere Version von puma_worker_killer benötigen, für eine Version 0.1.0 und für die andere Version 0.1.1. Beide Websites verwenden Ruby 2.5.3.
Wenn ich den Server mit RAILS_ENV=dev3 bundle exec pumactl -F ./config/puma.rb start
starte, wird in den Protokollen der folgende Fehler angezeigt und die Website hängt:
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)
Zuerst dachte ich, dass es ein Problem mit rbenv gewesen sein könnte, da ich die Edelsteine in ~ / .gem anstatt in ~ / .rbenv installiert hatte, also habe ich alle Rubine in ~ / .gem zerstört und sie frisch in die richtige installiert rbenv Ordner mit bundle install
und ich bekomme immer noch das gleiche Problem.
An dieser Stelle möchte ich klarstellen, dass ich online umfangreiche Recherchen zu diesem Thema durchgeführt habe und weiß, dass ich viele Dinge tun kann, um dies zu lösen.
Ich weiß, ich kann einfach die Version ändern und bundle update puma_worker_killer
.
Ich weiß auch, dass ich die neueste Version entfernen kann, indem ich gem uninstall puma_worker_killer
0.1.1 auswähle, aber dies würde bedeuten, dass die Abhängigkeiten von der anderen Website nicht erfüllt werden.
Ich habe mich ein wenig mit dem Quellcode von Bundler befasst und kann feststellen, dass dies durch die folgende Codezeile verursacht wird:
return if activated_spec.version == spec.version
Wenn Sie im Kontext des Bundlers bundle exec
sowohl mit als auch activated_spec
mit spec
match ausführen, bedeutet dies, dass der folgende Code in dieser Methode ( check_for_activated_spec!
) nicht ausgeführt wird. Wenn Sie den obigen Befehl activated_spec
ausführen , um den Server zu starten, ist (das aktivierte Gem) aus irgendeinem Grund die neueste Version (0.1.1) und nicht die in der Gemfile (0.1.0) aufgeführte, was bedeutet, dass es nicht zurückkehrt und wirft der Fehler oben.
Ich sollte auch erwähnen, dass es anscheinend auch das gleiche Problem mit get_process_mem gibt, das eine der Abhängigkeiten von puma_worker_killer ist. Es beschwert sich über die Aktivierung von 0.2.5, aber mein Gemfile möchte 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)
Nach meinem Verständnis von Bundler sollte es die in der Gemfile aufgeführte Version laden, wenn es verwendet wird bundle exec
, um genau diesem Problem entgegenzuwirken, dass mehrere Versionen desselben Gems vorhanden sind.
Ich weiß, dass ich auch ein separates Gemset erstellen könnte (was anscheinend mit rbenv möglich ist), das verschiedene Versionen von puma_worker_killer enthält und dann innerhalb des Projekts ausgeführt wird rbenv local 2.5.3-pwk0.1.0
oder rbenv local 2.5.3-pwk0.1.1
je nach gewünschter Version ausgeführt wird, aber das scheint übertrieben für das, was ich möchte leisten.
Bei dieser Geschwindigkeit bin ich versucht, einfach alle Websites mit der neuesten Version von puma_worker_killer und get_process_mem zu aktualisieren und sie dann zu sperren und alle älteren Versionen auf dem Server zu entfernen, aber ich denke nicht, dass ich das tun muss.
Weiß jemand, was hier passiert oder ob ich etwas krass Falsches mache?
Unten ist der Code, mit dem ich puma_worker_killer in meiner puma-Konfiguration verwende.
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
nicht wahr, da es nur die neueste Version von puma_worker_killer verwendet, die auf dem Server installiert istAntworten:
Was hier passiert, ist, dass Sie im Grunde mehrere Versionen des Edelsteins in Ihrem System haben.
Meistens verursachte es keine Probleme, da
bundle exec
die erforderlichen Versionen für Ihre Anwendung dynamisch geladen werden.In einigen Fällen enthalten Edelsteine Binärdateien. Ein solcher Fall
bundle exec
hilft nicht, da Sie nur eine Version in einem Moment verknüpfen können.Wenn Sie die Binärdatei als Alias aufrufen möchten, müssen Sie grundsätzlich für jede Anwendung ein separates Gemset verwenden.
Wenn Sie alle Edelsteine an einem Ort aufbewahren möchten, können Sie Binärdateien direkt aufrufen.
In Ihrem Fall wird es sein:
Mit der
_<version>_
Konstruktion können Sie die Version der Binärdatei angeben, die Sie ausführen möchten.Sie können auch Ihre benutzerdefinierte Binärdatei erstellen, z. B.
fake_pumactl
innerhalb des Projekts. Dadurch wird derGemfile.lock
Aufruf der Bibliothek überprüft und automatisch weitergeleitet, und die Version wird automatisch für Sie angegeben. Eine andere Möglichkeit besteht darin, die Gem-Version nach Shell-Skript zu analysieren und dieses Skript anstelle_<version>_
Ihres Aufrufs einzufügen.Hier ist das kurze Beispiel
puma_version
Die Variable kann aus dem Ergebnis eines Bash-Befehls definiert werden, aus dem die Gem-Version extrahiert wirdGemfile.lock
.quelle
RAILS_ENV=dev3 bundle exec pumactl _4.1.0_ -F ./config/puma.rb start
und es startet stattdessen 3.7.0 und nicht 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
Ich muss herausfinden, warum das so ist, aber Sie haben meine Frage tatsächlich beantwortet. Also danke und ich werde es als beantwortet markierenpumactl ${puma_version} -v
mit${pumactl_path} -v
als auch, sollte in Projektverzeichnis arbeiten , wopumactl_path
wird in einem binären innerhalb gem forlder als Pfad definiert werden.Gemfile.lock
Beeinflussen Sie möglicherweise das Ergebnis Ihres Befehls, da dieser eine ältere Version enthält.