2012-01-26 29 views
8

Tôi đã gặp phải sự cố này một vài lần và không thể tìm ra giải pháp nào nhưng giải pháp nhỏ nhất (xem bên dưới).Phương pháp an toàn để cập nhật gói R - là "trao đổi nóng" có thể?

Giả sử máy tính đang chạy hơn 2 trường hợp R, do 2+ người dùng hoặc 1 người dùng đang chạy nhiều quy trình và một phiên bản thực hiện update.packages(). Tôi đã có nhiều lần mà các trường hợp khác có thể nhận được phạm lỗi lên thời gian lớn. Các gói đang được cập nhật không thay đổi chức năng theo bất kỳ cách nào ảnh hưởng đến tính toán, nhưng bằng cách nào đó, một vấn đề lớn nảy sinh.

Giải pháp tầm thường (Giải pháp 0) là để chấm dứt tất cả các trường hợp của R trong khi update.packages() thực thi. Điều này có hơn 2 vấn đề. Đầu tiên, người ta phải chấm dứt các cá thể R. Thứ hai, người ta thậm chí không thể xác định nơi các cá thể đó đang chạy (xem cập nhật 1).

Giả sử rằng hành vi của mã đang được thực thi sẽ không thay đổi (ví dụ: cập nhật gói đều có lợi - chúng chỉ sửa lỗi, cải thiện tốc độ, giảm RAM và cấp kỳ lân), có cách nào đó để trao đổi nóng phiên bản mới của gói có ít tác động đến các quy trình khác?

Tôi có hai giải pháp ứng cử viên nhiều hơn, bên ngoài của R:

Giải pháp 1 là sử dụng một đường dẫn thư viện tạm thời và sau đó xóa các thư viện cũ cũ và di chuyển cái mới vào đúng vị trí của nó. Hạn chế của việc này là xóa + di chuyển có thể phải mất một thời gian mà không có gì khả dụng.

Giải pháp 2 là sử dụng liên kết tượng trưng để trỏ đến thư viện (hoặc hệ thống phân cấp thư viện) và chỉ ghi đè liên kết tượng trưng bằng con trỏ đến thư viện mới nơi gói được cập nhật. Điều đó dường như phải chịu ít thời gian ngừng gói hơn - thời gian cần để hệ điều hành ghi đè lên một liên kết tượng trưng. Nhược điểm của điều này là nó đòi hỏi nhiều sự chăm sóc hơn trong việc quản lý các liên kết tượng trưng, ​​và đặc trưng cho nền tảng.

tôi nghi ngờ rằng giải pháp # 1 có thể được sửa đổi để được như # 2, bằng cách sử dụng thông minh của .libPaths(), nhưng điều này có vẻ như người ta cần đến không gọi update.packages() và thay vào đó viết một updater mới tìm thấy các gói lỗi thời, cài đặt chúng vào một thư viện tạm thời, và sau đó cập nhật các đường dẫn thư viện. Điểm mấu chốt của điều này là người ta có thể hạn chế quy trình hiện tại thành .libPaths() khi nó bắt đầu (tức là thay đổi đường dẫn thư viện R biết về có thể không được truyền cho những trường hợp đang chạy, mà không có sự can thiệp rõ ràng nào trong trường hợp đó).


Cập nhật 1. Trong trường hợp ví dụ, hai phiên bản R cạnh tranh nằm trên cùng một máy. Đây không phải là một yêu cầu: nếu tôi hiểu các bản cập nhật, nếu cả hai chia sẻ cùng một thư viện, nghĩa là cùng một thư mục trên ổ đĩa được chia sẻ, thì bản cập nhật vẫn có thể gây ra sự cố, ngay cả khi phiên bản R khác trên máy khác . Vì vậy, người ta có thể vô tình giết chết một quá trình R và thậm chí không nhìn thấy nó.

Trả lời

3

Đoán mạnh của tôi là không có cách nào xung quanh việc này.

Đặc biệt khi một gói bao gồm mã được biên dịch, bạn không thể xóa và thay thế DLL trong khi nó đang được sử dụng và mong đợi nó vẫn hoạt động. Tất cả các con trỏ vào DLL được sử dụng bởi các cuộc gọi R đến các chức năng đó sẽ yêu cầu một vị trí bộ nhớ cụ thể và tìm thấy nó không thể giải thích được. (Lưu ý - trong khi tôi sử dụng thuật ngữ "DLL" ở đây, tôi có nghĩa là nó trong một ý nghĩa không-Windows cụ thể, vì nó được sử dụng, ví dụ, trong tập tin trợ giúp cho ?getLoadedDLLs. "Thư viện được chia sẻ" có lẽ là thuật ngữ chung tốt hơn .)

(Một số khẳng định nghi ngờ của tôi xuất phát từ the R for Windows FAQ, mà báo cáo rằng 'Windows ổ khóa [a] gói của DLL trong khi nó được nạp' có thể gây update.packages() thất bại.)

Tôi không chắc chắn chính xác như thế nào Cơ chế tải lười của R được thực hiện, nhưng hãy tưởng tượng rằng nó cũng có thể bị sai lầm bởi việc loại bỏ các đối tượng mà nó mong muốn tìm thấy tại một địa chỉ cụ thể trong máy.

Một người nào khác biết nhiều hơn về nội bộ của máy tính chắc chắn sẽ đưa ra câu trả lời tốt hơn điều này, nhưng đó là những suy nghĩ của tôi.

+0

Đây là một tâm điểm. Tôi nghi ngờ rằng vấn đề của một thư viện được chia sẻ là một vấn đề trên các hệ điều hành. Đối với hầu hết việc sử dụng, tôi có khuynh hướng tin rằng điều này sẽ giết chết ý tưởng của việc thay đổi nóng. Trường hợp hẹp nhất sẽ dành cho các gói không sử dụng các thư viện chia sẻ bên ngoài, nhưng tôi không chắc nó hoạt động như thế nào cho các gói hoàn toàn trong R. – Iterator

+0

Tôi nghĩ câu trả lời của bạn khá nhiều đè bẹp giấc mơ của hotswapping nói chung. Ngay cả khi tôi có một gói R thuần túy mà tôi muốn cập nhật, thì đó không phải là một thực hành tốt để cho rằng tôi có thể làm điều này. Vincent có một câu trả lời hợp lý về cách người ta có thể làm phiên bản, thay vì hoán đổi, tôi sẽ phải thích nghi một chút, nhưng rõ ràng đó là cách duy nhất xung quanh những xung đột bạn đã chỉ ra. – Iterator

4

Trong môi trường sản xuất, bạn có thể muốn giữ ít nhất hai phiên bản, phiên bản hiện tại và phiên bản trước đó, để có thể nhanh chóng chuyển về phiên bản cũ trong trường hợp có sự cố. Không có gì sẽ bị ghi đè hoặc xóa. Nó dễ dàng hơn để làm điều đó cho toàn bộ hệ sinh thái R: bạn sẽ có một số thư mục, nói "R-2.14.1-2011-12-22", "R-2.14.1-2012-01-27", v.v. mỗi chứa tất cả mọi thứ (các tập tin thực thi R và tất cả các gói). Những thư mục đó sẽ không bao giờ được cập nhật: nếu cần cập nhật, thư mục mới sẽ được tạo. (Một số hệ thống tệp cung cấp "ảnh chụp nhanh" cho phép bạn có nhiều thư mục rất giống nhau mà không cần sử dụng dung lượng đĩa quá mức.)

Chuyển từ phiên bản này sang phiên bản khác có thể được thực hiện ở phía người dùng, khi người dùng khởi chạy R, bằng cách thay thế tệp thực thi R bằng tập lệnh có thể sử dụng đúng phiên bản hoặc bằng cách đặt biến môi trường PATH để trỏ đến phiên bản mong muốn. Điều này đảm bảo rằng một phiên nhất định luôn thấy cùng một phiên bản của mọi thứ.

+0

Đây là một gợi ý tốt, cả về khả năng hoàn nguyên/"lùi lại" thay đổi và khả năng tái tạo kết quả. Tôi cần cung cấp cho nó một số suy nghĩ thêm về chi phí truyền thông thông tin phiên bản. – Iterator

+0

Tôi nghĩ bạn đã đưa ra câu trả lời hay nhất về các phương pháp hay nhất. Câu trả lời của Josh tập trung nhiều hơn vào lý do tại sao không có phương pháp an toàn để trao đổi nóng. Trên cơ sở câu trả lời của ông, mà tôi đã chọn, tôi muốn nói rằng địa chỉ trả lời của bạn cần phải làm gì để giải quyết những vấn đề đó. – Iterator

1

Dưới đây là một kịch bản tôi gặp ngày hôm qua trên Windows 7.

  1. Tôi đang chạy một phiên R.
  2. Mở tệp PDF của hướng dẫn sử dụng gói.
  3. Đóng tất cả các phiên R. Hãy quên đóng gói PDF thủ công.
  4. mở một trường hợp mới của R, update.packages chạy()

Các cài đặt thất bại tất nhiên bởi vì Windows vẫn có pdf mở và không thể ghi đè lên nó ....

+0

+1 Điều đó sẽ khá tệ trong môi trường chia sẻ. Tôi đã không thử nghiệm dưới Linux với nhiều người dùng, nhưng tôi tự hỏi làm thế nào mà sẽ làm việc cho một tình huống với, nói rằng, 100 người dùng và ai đó đang đọc một gói họa tiết ... – Iterator

+0

Trên Linux, điều đó sẽ không gây ra bất kỳ vấn đề nào: theo mặc định, các tệp đang sử dụng không bị khóa. Nếu tệp PDF vẫn còn ở đó sau khi cập nhật, trình xem PDF sẽ nhận thấy thay đổi, làm mới và hiển thị tệp mới. Nếu tệp PDF không còn ở đó, trình xem PDF có thể sẽ tiếp tục hiển thị tệp cũ (tệp không thực sự bị xóa, tệp đang ở trạng thái tạm dừng, vẫn ở đó, không có tên và sẽ chỉ thực sự biến mất khi tất cả các ứng dụng đọc nó đóng tệp). Trong trường hợp xấu nhất, trình xem PDF sẽ hiển thị thông báo lỗi - nhưng nó sẽ không ngăn cập nhật. –

Các vấn đề liên quan