Làm cách nào để khắc phục sự cố với trình đóng gói yêu cầu phiên bản đá quý mới nhất khi tôi cần một phiên bản khác?


8

Tôi đã gãi đầu với cái này gần 2 tuần rồi. Tôi có một máy chủ Ubuntu 14.04 với rbenv được cài đặt đang chạy một số trang web Rails khác nhau, một số trong số chúng trên các phiên bản cũ hơn của Rails, một số trong số chúng trên phiên bản mới nhất.

Tôi có 2 trang web đặc biệt là cả hai đều yêu cầu một phiên bản khác nhau của puma_worker_killer, 1 yêu cầu 0.1.0 và 0.1.1 khác. Cả hai trang web này đều sử dụng Ruby 2.5.3.

Khi tôi khởi động máy chủ, RAILS_ENV=dev3 bundle exec pumactl -F ./config/puma.rb starttôi gặp lỗi sau trong nhật ký và trang web bị treo:

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)

Lúc đầu, tôi nghĩ rằng đó có thể là một vấn đề với rbenv vì tôi đã cài đặt các viên đá quý trong ~ / .gem thay vì trong ~ / .rbenv vì vậy tôi đã thu thập tất cả các viên hồng ngọc trong ~ / .gem và cài đặt chúng mới vào đúng thư mục rbenv với bundle install và tôi vẫn gặp vấn đề tương tự.

Bây giờ tại thời điểm này tôi muốn làm rõ rằng tôi đã thực hiện nghiên cứu sâu rộng về chủ đề này trực tuyến và tôi biết rằng tôi có thể làm nhiều việc để giải quyết vấn đề này.

Tôi biết tôi chỉ có thể thay đổi phiên bản và bundle update puma_worker_killer .

Tôi cũng biết tôi có thể loại bỏ phiên bản mới nhất bằng cách thực hiện gem uninstall puma_worker_killer và chọn 0.1.1 nhưng điều này có nghĩa là sự phụ thuộc vào trang web khác sẽ không được đáp ứng.

Tôi đã thực hiện một số nghiên cứu về mã nguồn của trình đóng gói và có thể thấy rằng điều đó gây ra bởi dòng mã sau:

return if activated_spec.version == spec.version

Khi chạy trong ngữ cảnh của trình đóng gói sử dụng bundle execcả hai activated_specspeckhớp, có nghĩa là đoạn mã sau trong phương thức đó ( check_for_activated_spec!) không chạy. Vì một số lý do, khi chạy lệnh trên để khởi động máy chủ,activated_spec (đá quý được kích hoạt) là phiên bản mới nhất (0.1.1) và không phải là phiên bản được liệt kê trong Gemfile (0.1.0), có nghĩa là nó không quay lại và ném các lỗi trên.

Tôi cũng nên đề cập rằng dường như cũng có vấn đề tương tự với get_ process_mem, một trong những phụ thuộc của puma_worker_killer. Nó phàn nàn về việc đã kích hoạt 0.2.5 nhưng Gemfile của tôi muốn 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)

Theo hiểu biết của tôi về trình đóng gói, nó nên tải phiên bản được liệt kê trong Gemfile khi sử dụng bundle execđể chống lại chính vấn đề này khi có nhiều phiên bản của cùng một loại đá quý.

Tôi biết tôi cũng có thể tạo một gemet riêng (có thể được thực hiện với rbenv rõ ràng) có các phiên bản khác nhau của puma_worker_killer trong đó và sau đó chạy rbenv local 2.5.3-pwk0.1.0hoặcrbenv local 2.5.3-pwk0.1.1 tùy thuộc vào phiên bản tôi muốn, trong dự án, nhưng điều đó dường như quá mức cho những gì tôi muốn Hoàn thành.

Với tốc độ này, tôi chỉ muốn cập nhật tất cả các trang web với phiên bản mới nhất của cả puma_worker_killer và get_ process_mem và sau đó khóa chúng và xóa tất cả các phiên bản cũ hơn trên máy chủ, nhưng tôi không nghĩ mình nên làm điều đó.

Có ai biết những gì đang xảy ra ở đây hoặc liệu tôi đang làm gì đó sai trái?

Dưới đây là đoạn mã tôi sử dụng để sử dụng puma_worker_killer trong cấu hình puma của tôi.

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

1
Tôi thường đặt môi trường của mình bên trong docker cho từng dự án, vì vậy thiết lập sẽ không can thiệp lẫn nhau. Cũng không khó để gắn một thư mục từ máy chủ vào ví dụ docker, mặc dù đôi khi việc duy trì hình ảnh có thể hơi khó khăn một chút. Trong trường hợp đó, tôi thường thiết lập một docker mới và gắn kết từ thư mục máy chủ để bắt đầu lại.
bóng tối

Bạn nên xóa tệp Gemfile.lock của mình và sau đó chạy lại cài đặt gói - nó sẽ xóa tất cả các số phiên bản không được chỉ định và cố gắng tạo một bộ đá quý tương thích với nhau, ném lỗi và giải thích các xung đột nếu không thể
Đánh dấu

@darkash yeah docker sẽ là cách lý tưởng để đi với điều này. Đó là trong kế hoạch cải tiến trong tương lai nhưng tôi chỉ đang cố gắng khắc phục vấn đề tức thời này để tôi có thể khiến tất cả các trang web cư xử tốt với nhau trên cùng một máy chủ
Arran Scott

1
@Mark yeah, tôi biết tôi cũng có thể làm điều đó nhưng điều đó chỉ tương tự với việc chạy bundle update puma_worker_killerkhông thực sự vì nó sẽ chỉ sử dụng phiên bản mới nhất của puma_worker_killer được cài đặt trên máy chủ
Arran Scott

Câu trả lời:


1

Điều đang xảy ra ở đây về cơ bản là bạn có một vài phiên bản đá quý trong hệ thống của mình.

Hầu hết thời gian nó không gây ra sự cố vì bundle execsẽ tự động tải các phiên bản cần thiết cho ứng dụng của bạn.

Trong một số trường hợp, đá quý sẽ có tệp nhị phân đi kèm. Trường hợp như vậy bundle execsẽ không giúp ích gì vì bạn chỉ có thể có một phiên bản được liên kết trong một khoảnh khắc.

Về cơ bản, nếu bạn muốn gọi nhị phân bằng bí danh, bạn phải sử dụng gemet riêng cho mỗi ứng dụng.

Nếu bạn muốn giữ tất cả các viên đá quý ở một nơi, bạn có thể gọi các tệp nhị phân trực tiếp.

Trong trường hợp của bạn, nó sẽ là:

RAILS_ENV=dev3 bundle exec pumactl _0.1.0_ -F ./config/puma.rb

Cấu _<version>_trúc cho phép bạn chỉ định phiên bản của tệp nhị phân bạn muốn chạy.

Bạn cũng có thể tạo nhị phân tùy chỉnh của mình, như fake_pumactlbên trong dự án sẽ kiểm traGemfile.lock và tự động ủy quyền cuộc gọi của bạn đến thư viện và chỉ định phiên bản tự động cho bạn. Một cách khác là phân tích phiên bản đá quý bằng tập lệnh shell và đặt tập lệnh này thay vì _<version>_trong cuộc gọi của bạn.

Dưới đây là ví dụ ngắn gọn

$ gem install puma
Fetching puma-4.3.3.gem

$ gem install puma -v 4.3.0
Fetching puma-4.3.0.gem

$ pumactl -v
4.3.3

$ pumactl _4.3.0_ -v
4.3.0

$ ruby -v
ruby 2.6.3p62

$ export puma_version=_4.3.0_
$ pumactl ${puma_version} -v
4.3.0

puma_versionbiến có thể được định nghĩa từ kết quả của lệnh bash sẽ trích xuất phiên bản đá quý từ đó Gemfile.lock.


Cảm ơn câu trả lời của bạn. Tôi biết tôi có thể đi theo con đường tạo ra một viên đá quý riêng biệt nhưng tôi không thực sự muốn làm điều đó. Tôi thích cách bạn đề cập đến việc chỉ định một tệp nhị phân cụ thể với phiên bản. Tôi vừa mới thử nó và nó dường như không hoạt động. Trên một ứng dụng cụ thể này, tôi có Puma 3.7.0 là phiên bản được chỉ định trong Gemfile, nhưng cũng đã cài đặt 4.1.0. Tôi chạy lệnh sau: RAILS_ENV=dev3 bundle exec pumactl _4.1.0_ -F ./config/puma.rb startvà nó bắt đầu 3.7.0 thay vì 4.1.0 ( Version 3.7.0 (ruby 2.5.3-p105), codename: Snowy Sagebrush)
Arran Scott

Bạn cũng có thể giải thích cho tôi cách bạn làm điều này không? 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.
Arran Scott

Tôi đã mở rộng câu trả lời
achempion

Cảm ơn. Thật kỳ lạ, điều này hoạt động khi tôi nằm ngoài thư mục gốc của dự án Rails nhưng sau đó khi tôi cd vào một trong những thư mục thì nó không hoạt động ... ➜ 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 Tôi cần tìm hiểu tại sao lại như vậy nhưng bạn thực sự đã trả lời câu hỏi của tôi, cảm ơn và tôi sẽ đánh dấu nó như đã trả lời
Arran Scott

Bạn cũng có thể thay thế pumactl ${puma_version} -vbằng ${pumactl_path} -v, nên hoạt động bên trong thư mục dự án, nơi pumactl_pathsẽ được xác định là đường dẫn đến một nhị phân trong gem forlder. Có thể Gemfile.lockảnh hưởng đến kết quả của lệnh của bạn vì nó chứa phiên bản cũ hơn.
achempion
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.