2012-01-26 22 views
8

Kilka razy spotkałem się z tym problemem i nie jestem w stanie wymyślić żadnego rozwiązania, ale trywialnego (patrz poniżej).Bezpieczna metoda aktualizacji pakietów R - czy możliwe jest "hot-swap"?

Załóżmy, że komputer ma 2 lub więcej wystąpień R, z powodu użytkowników 2+ lub 1 użytkownika z wieloma procesami, a jedno wystąpienie wykonuje update.packages(). Miałem kilka razy, kiedy druga instancja może zostać sfaulowana. Aktualizowane pakiety nie zmieniają funkcjonalności w żaden sposób wpływający na obliczenia, ale w jakiś sposób powstaje duży problem.

Rozwiązaniem trywialnym (Rozwiązanie 0) jest zakończenie wszystkich wystąpień R podczas wykonywania update.packages(). To ma 2+ problemy. Po pierwsze, należy zakończyć instancje R. Po drugie, nie można nawet stwierdzić, gdzie te instancje są uruchomione (patrz aktualizacja 1).

Założenie, że zachowanie wykonywanego kodu nie zmieni się (np. Aktualizacje pakietów są korzystne - naprawiają tylko błędy, zwiększają szybkość, zmniejszają ilość pamięci RAM i udzielają jednorożców), czy istnieje sposób na szybką zamianę nowa wersja pakietu z mniejszym wpływem na inne procesy?

Mam dwa kolejne rozwiązania kandydujących, poza R:

Rozwiązanie 1 jest użycie ścieżki biblioteki tymczasowej, a następnie usunąć stary biblioteki i przenieść nowy na swoim miejscu. Wadą tego jest to, że usunięcie + ruchów może spowodować pewien czas, w którym nic nie jest dostępne.

Rozwiązanie 2 polega na użyciu dowiązań symbolicznych w celu wskazania biblioteki (lub hierarchii biblioteki) i wystarczy zastąpić dowiązanie symboliczne wskaźnikiem do nowej biblioteki, w której znajduje się zaktualizowany pakiet. Wydaje się, że czas przestoju pakietu jest krótszy - czas, w którym system operacyjny musi nadpisać dowiązanie symboliczne. Wadą tego jest to, że wymaga dużo więcej staranności w zarządzaniu dowiązaniami symbolicznymi i jest specyficzna dla platformy.

Podejrzewam, że rozwiązanie nr 1 może zostać zmodyfikowany tak, aby być jak # 2, poprzez inteligentne wykorzystanie .libPaths(), ale to wydaje się jak trzeba nie rozmowy update.packages() i zamiast napisać nowy updater że znajdzie przestarzałe pakiety, instaluje do biblioteki tymczasowej, a następnie aktualizuje ścieżki biblioteki. Plusem tego jest to, że można ograniczyć istniejący proces do .libPaths(), który miał on, gdy się rozpoczął (tj. Zmiana ścieżek biblioteki, o których R wie, może nie być propagowana do tych instancji, które już są uruchomione, bez wyraźnej interwencji w tej instancji).


Aktualizacja 1. W tym scenariuszu dwie konkurujące ze sobą instancje R znajdują się na tym samym komputerze. Nie jest to wymagane: o ile rozumiem aktualizacje, jeśli te dwie biblioteki mają wspólne biblioteki, tj. Te same katalogi na wspólnym dysku, aktualizacja może nadal powodować problemy, nawet jeśli druga instancja R znajduje się na innej maszynie . Tak więc można przypadkowo zabić proces R, a nawet go nie zobaczyć.

Odpowiedz

3

Przypuszczam, że nie da się tego obejść.

Szczególnie, gdy pakiet zawiera skompilowany kod, nie można usunąć i zastąpić biblioteki DLL, gdy jest ona używana, i oczekiwać, że nadal będzie działać. Wszystkie wskaźniki do biblioteki DLL używanej przez wywołania R do tych funkcji będą prosić o określone miejsce w pamięci i znaleźć go w niewytłumaczalny sposób. (Uwaga - podczas gdy używam tutaj terminu "DLL", mam na myśli to w sensie innym niż Windows, ponieważ jest używany, np. W pliku pomocy dla ?getLoadedDLLs. "Biblioteka współdzielona" jest prawdopodobnie lepszym ogólnym terminem .)

(Niektóre potwierdzenie moich podejrzeń pochodzi z the R for Windows FAQ, który donosi, że „Zamki Okna [A] pakiet za DLL, gdy jest załadowany”, co może powodować update.packages() na niepowodzenie.)

nie jestem pewien dokładnie, jak Mechanizm Lazy-load jest zaimplementowany, ale wyobraź sobie, że można go zneutralizować przez usunięcie obiektów, które spodziewa się znaleźć pod konkretnymi adresami w maszynie.

Ktoś, kto wie więcej o wnętrzach komputerów, na pewno udzieli lepszej odpowiedzi, ale to są moje przemyślenia.

+0

To jest ważny punkt. Podejrzewam, że problem z udostępnioną biblioteką jest problemem w różnych systemach operacyjnych. Dla większego użycia jestem skłonny uwierzyć, że to zabija ideę hotswapping. Najmniejszy przypadek dotyczy pakietów, które nie korzystają z zewnętrznych bibliotek współdzielonych, ale nie jestem pewien, jak to działa w przypadku pakietów, które są w całości w stanie R. – Iterator

+0

Myślę, że twoja odpowiedź niemal całkowicie niszczy marzenia o upuszczaniu na gorąco. Nawet jeśli mam czysty pakiet R, który chciałbym zamienić na gorąco, to nie jest dobrą praktyką zakładanie, że mogę to zrobić. Vincent ma rozsądną odpowiedź na to, jak można raczej pisać, a nie wymieniać, co będę musiał zaadaptować całkiem sporo, ale jasne jest, że jest to jedyny sposób na wskazanie konfliktów. – Iterator

4

W środowisku produkcyjnym prawdopodobnie zachowasz przynajmniej dwie wersje, bieżącą i poprzednią, aby móc szybko powrócić do starej wersji w przypadku wystąpienia problemu. Nic nie zostanie nadpisane ani usunięte. Łatwiej jest to zrobić dla całego ekosystemu R: masz kilka katalogów, np. "R-2.14.1-2011-12-22", "R-2.14.1-12-01-01" itp., każda zawiera wszystko (pliki wykonywalne R i wszystkie pakiety). Te katalogi nigdy nie zostaną zaktualizowane: jeśli potrzebna jest aktualizacja, zostanie utworzony nowy katalog. (Niektóre systemy plików zapewniają "migawki", które pozwalają na posiadanie wielu bardzo podobnych katalogów bez zbędnego wykorzystania miejsca na dysku.)

Przełączanie z jednej wersji na drugą można przeprowadzić po stronie użytkownika, gdy użytkownicy uruchamiają R, albo zastępując plik wykonywalny R skryptem, który używałby poprawnej wersji, lub ustawiając zmienną środowiskową PATH tak, aby wskazywała na żądaną wersję. Zapewnia to, że dana sesja zawsze widzi tę samą wersję wszystkiego.

+0

Jest to dobra sugestia, zarówno jeśli chodzi o możliwość zmiany/cofnięcia zmian, jak i możliwość reprodukcji wyników. Muszę poświęcić mu trochę więcej uwagi na temat przekazywania informacji o wersji. – Iterator

+0

Myślę, że dałeś świetną odpowiedź na temat najlepszych praktyk. Odpowiedź Josh jest bardziej skoncentrowana na tym, dlaczego nie ma bezpiecznej metody na hotswapping. Na podstawie jego odpowiedzi, którą wybrałem, chciałbym powiedzieć, że odpowiedź adresowa, co należy zrobić, aby rozwiązać takie problemy. – Iterator

1

Oto scenariusz natknąłem się wczoraj na Windows 7.

  1. Używam sesję R.
  2. Otwórz plik PDF instrukcji obsługi pakietu.
  3. Zamknij wszystkie sesje R. Zapomnij o zamknięciu ręcznego pliku PDF pakietu.
  4. otworzyć nowe wystąpienie R, prowadzone update.packages()

Instalator nie powiedzie się, oczywiście, ponieważ system Windows nadal ma pdf otwarte i nie można go zastąpić ....

+0

+1 Byłoby całkiem źle we wspólnym środowisku. Nie testowałem pod Linuksem z wieloma użytkownikami, ale zastanawiam się, jak to by działało w sytuacji z, powiedzmy, 100 użytkownikami i kimś czytającym winietę pakietu ... – Iterator

+0

W systemie Linux nie stanowiłoby to żadnego problemu: domyślnie pliki w użyciu nie są zablokowane. Jeśli plik PDF nadal istnieje po aktualizacji, przeglądarka plików PDF zauważy zmianę, odświeży i wyświetli nową. Jeśli pliku PDF już tam nie ma, przeglądarka PDF prawdopodobnie nadal będzie wyświetlać stary plik (plik nie jest tak naprawdę usunięty, jest w stanie zawieszenia, nadal tam, bez nazwy, i będzie naprawdę znikają , gdy wszystkie aplikacje, które go czytają, zamykają plik). W najgorszym przypadku przeglądarka PDF wyświetli komunikat o błędzie - ale nie uniemożliwi aktualizacji. –

Powiązane problemy