8
votes

Méthode de sécurité pour la mise à jour des forfaits R - est «Échange à chaud» possible?

J'ai rencontré ce problème plusieurs fois et je ne suis pas capable de comprendre une solution mais le trivial (voir ci-dessous).

Supposons qu'un ordinateur exécute 2+ instances de R, en raison des utilisateurs de 2+ ou de 1 utilisateur exécutant plusieurs processus, et une instance exécute update.backages () . J'ai eu plusieurs fois où l'autre instance peut être encrassée grosse fois. Les paquets mis à jour ne changent de fonctionnalité de quelque manière que ce soit qui affecte le calcul, mais d'une manière ou d'une autre, un gros problème se pose.

La solution triviale (solution 0) consiste à terminer toutes les instances de R tandis que update.backages () exécute. Cela a plus de 2 problèmes. Premièrement, il faut mettre fin à des instances r. Deuxièmement, on peut même ne pas être capable d'identifier où ces instances sont en cours d'exécution (voir Mise à jour 1).

En supposant que le comportement du code exécuté ne changera pas (par exemple, les mises à jour des packages sont toutes bénéfiques - elles ne résolvent que des bugs, améliorent la vitesse, réduisent la RAM et accordent des licornes), existe-t-il un moyen d'échanger une nouvelle Version du paquet avec moins d'impact sur d'autres processus?

J'ai deux autres solutions candidates, en dehors de R:

solution 1 est d'utiliser un chemin de bibliothèque temporaire, puis de supprimer la vieille vieille bibliothèque et de déplacer le nouveau à sa place. L'inconvénient de ceci est que les suppressions + les mouvements peuvent entraîner un peu de temps pendant lequel rien n'est disponible.

Solution 2 est d'utiliser des liens symboliques pour pointer vers une bibliothèque (ou une hiérarchie de la bibliothèque) et il suffit de remplacer un symbolique avec un pointeur sur une nouvelle bibliothèque où réside le package mis à jour. Cela semble encourager encore moins de temps d'arrêt du paquet - le temps qu'il faut pour le système d'exploitation pour écraser un lien symbolique. L'inconvénient est que cela nécessite beaucoup plus de soin de gérer les liens symboliques et est spécifique à la plate-forme.

Je soupçonne que la solution n ° 1 pourrait être modifiée comme étant comme n ° 2, par une utilisation intelligente de .libpaths () , mais cela semble que l'on doit pas appeler update.backages () et écrivez plutôt une nouvelle mise à jour qui trouve les packages obsolètes, les installe dans une bibliothèque temporaire, puis met à jour les chemins de la bibliothèque. L'avantage de ceci est que l'on pourrait contraindre un processus existant au .libpaths () il avait commencé quand il a commencé (c.-à-dire que changer les chemins de la bibliothèque r sait ne peut pas être propagé à ces instances qui sont déjà exécutées , sans une intervention explicite dans ce cas).


Mise à jour 1. Dans l'exemple Scénario, les deux instances R en compétition sont sur la même machine. Ce n'est pas une exigence: autant que je comprenne les mises à jour, si les deux partagent les mêmes bibliothèques, c'est-à-dire les mêmes répertoires sur un lecteur partagé, la mise à jour peut toujours causer des problèmes, même si l'autre instance de R est sur une autre machine. . Donc, on pourrait accidentellement tuer un processus r et même le voir même.


0 commentaires

3 Réponses :


3
votes

Ma forte estimation est qu'il n'y a aucun moyen de cela.

Surtout lorsqu'un package inclut le code compilé, vous ne pouvez pas supprimer et remplacer la DLL pendant son utilisation et s'attendre à ce que cela fonctionne toujours. Tous les pointeurs dans la DLL utilisés par R appels à ces fonctions demanderont un emplacement de mémoire particulier et le trouveront inexplicablement parti. (Remarque - alors que j'utilise le terme "dll" ici, je le pense en un sens non spécifique aux fenêtres, comme il est utilisé, par exemple, dans le fichier d'aide pour ? GetLoDeddlls " Bibliothèque "est peut-être le meilleur terme générique.)

(une certaine confirmation de mes soupçons provient de the r Pour Windows FAQ , qui rapporte que «Windows verrouille la DLL de Windows [a] le package lorsqu'il est chargé» pouvant causer update.backages () pour échouer.)

Je ne sais pas exactement comment le mécanisme de charge paresseux de R est mis en œuvre, mais imaginez que cela pourrait également être salué par élimination des objets qu'il prévoit de trouver à une adresse particulière de la machine.

Quelqu'un d'autre qui en sait plus sur les internes des ordinateurs donnera sûrement une meilleure réponse que cela, mais ce sont mes pensées.


2 commentaires

C'est un point important. Je soupçonne que la question d'une bibliothèque partagée est un problème entre les systèmes d'exploitation. Pour la plupart des utilisations, je suis enclin à croire que cela tue l'idée de hommage. Le cas le plus étroit serait pour les emballages qui n'utilisent pas de bibliothèques partagées externes, mais je ne sais pas comment cela fonctionne pour des packages entièrement dans R.


Je pense que votre réponse écrase à peu près le rêve de hommage en général. Même si j'ai un package P pur que j'aimerais faire chaud, ce n'est pas une bonne pratique pour supposer que je peux le faire. Vincent a une réponse raisonnable pour la façon dont on peut faire des versions, plutôt que d'échanger, ce que je devrai vous adapter un peu, mais il est clair que c'est le seul moyen de contourner les conflits que vous avez signalés.



4
votes

Dans un environnement de production, vous souhaitez probablement conserver au moins deux versions, le courant et le précédent, afin de pouvoir passer rapidement à l'ancienne en cas de problème. Rien ne serait écrasé ou supprimé. Il est plus facile de le faire pour l'écosystème complet: vous auriez plusieurs répertoires, disons "R-2.14.1-2011-12-22", "R-2.14.1-2012-01-27", etc., chacun contenant tout (les exécutables R et tous les paquets). Ces répertoires ne seraient jamais mis à jour: si une mise à jour est nécessaire, un nouveau répertoire serait créé. (Certains systèmes de fichiers fournissent des "instantanés" qui vous permettraient de disposer de nombreux répertoires très similaires sans utilisation d'espace disque indue.)

La commutation d'une version à l'autre pourrait être effectuée du côté de l'utilisateur, lorsque les utilisateurs lancent R, soit en remplaçant l'exécutable R avec un script qui utiliserait la version correcte, soit en définissant la variable d'environnement de passage pour pointer vers le Version souhaitée. Cela garantit qu'une session donnée voit toujours la même version de tout.


2 commentaires

C'est une bonne suggestion, à la fois pour la capacité de rétablir / "retourner" les changements et la capacité de reproduire des résultats. Je dois lui donner une plus grande pensée concernant la surcharge de la communication des informations de version.


Je pense que vous avez donné une bonne réponse sur les meilleures pratiques. La réponse de Josh est plus concentrée sur la raison pour laquelle il n'y a pas de méthode sans danger pour hommage. Sur la base de sa réponse, que j'ai sélectionnée, je dirais que votre réponse doit être prise sur ce qui devrait être fait afin de résoudre ces problèmes.



1
votes

Voici un scénario que j'ai rencontré hier sur Windows 7.

  1. Je cours une session R.
  2. Ouvrez le PDF d'un manuel d'emballage.
  3. Fermer toutes les sessions R. Oublier de fermer le manuel d'emballage PDF.
  4. Ouvrez une nouvelle instance de r, exécutation update.backages ()

    L'installation échoue bien sûr car Windows a toujours le PDF ouvert et ne peut pas l'écraser ....


2 commentaires

+1 ce serait plutôt mauvais dans un environnement partagé. Je n'ai pas testé sous Linux avec plusieurs utilisateurs, mais je me demande comment cela fonctionnerait pour une situation avec, dire, 100 utilisateurs et que quelqu'un lisait une vignette ...


Sur Linux, cela ne poserait aucun problème: par défaut, les fichiers utilisés ne sont pas verrouillés. Si le fichier PDF est toujours là après la mise à jour, la visionneuse PDF remarquerait la modification, l'actualisation et l'affichage du nouveau. Si le fichier PDF n'est plus là, le visualiseur PDF continuerait probablement à afficher l'ancien (le fichier n'est pas vraiment supprimé, il est dans un état de limbe, toujours là, sans nom et ne disparaîtra vraiment que lorsque toutes les applications la lire fermer le fichier). Dans le pire des cas, le visualiseur PDF afficherait un message d'erreur - mais cela n'empêcherait pas la mise à jour.