2012-01-26 7 views
8

Ho riscontrato questo problema alcune volte e non sono in grado di trovare alcuna soluzione tranne quella banale (vedi sotto).Metodo sicuro per l'aggiornamento dei pacchetti R: lo "scambio a caldo" è possibile?

Supponiamo che un computer stia eseguendo 2 o più istanze di R, a causa di 2+ utenti o 1 utente che esegue più processi e un'istanza esegue update.packages(). Ho avuto diverse volte in cui l'altra istanza può essere messa in difficoltà alla grande. I pacchetti in fase di aggiornamento non modificano la funzionalità in alcun modo che influisce sul calcolo, ma in qualche modo si pone un grosso problema.

La soluzione banale (Soluzione 0) è di terminare tutte le istanze di R mentre si esegue update.packages(). Questo ha 2 o più problemi. Primo, uno deve terminare le istanze R. Secondo, uno potrebbe non essere nemmeno in grado di identificare dove sono in esecuzione quelle istanze (vedere l'aggiornamento 1).

Supponendo che il comportamento del codice in esecuzione non cambierà (ad esempio, gli aggiornamenti dei pacchetti sono tutti vantaggiosi - risolvono solo bug, migliorano la velocità, riducono la RAM e concedono gli unicorni), c'è un modo per scambiare a caldo un nuova versione del pacchetto con minore impatto su altri processi?

Ho altre due soluzioni candidate, al di fuori della R:

Soluzione 1 è quello di utilizzare un percorso di libreria temporanea e quindi eliminare il vecchio vecchia biblioteca e spostare il nuovo al suo posto. Lo svantaggio di questo è che cancella + mosse può incorrere in un tempo durante il quale nulla è disponibile.

Soluzione 2 utilizza i collegamenti simbolici per puntare a una libreria (o una gerarchia di libreria) e sovrascrive semplicemente un collegamento simbolico con un puntatore a una nuova libreria in cui risiede il pacchetto aggiornato. Ciò sembra comportare anche meno tempi di inattività del pacchetto: il tempo impiegato dal sistema operativo per sovrascrivere un collegamento simbolico. Lo svantaggio di questo è che richiede molta più attenzione nella gestione dei collegamenti simbolici ed è specifico per la piattaforma.

Ho il sospetto che la soluzione # 1 potrebbe essere modificato per essere come # 2, con l'uso intelligente di .libPaths(), ma questo mi sembra uno ha bisogno di non chiamata update.packages() e invece scrivere un nuovo aggiornamento che trova i pacchetti obsoleti, installazioni li a una libreria temporanea e quindi aggiorna i percorsi della libreria. Il lato positivo di questo è che si potrebbe vincolare un processo esistente allo .libPaths() che aveva quando è stato avviato (cioè modificare i percorsi della libreria che R sa potrebbe non essere propagato a quelle istanze già in esecuzione, senza alcun intervento esplicito all'interno di quell'istanza).


Aggiornamento 1. Nello scenario di esempio, le due istanze R concorrenti si trovano sulla stessa macchina. Questo non è un requisito: per quanto riguarda gli aggiornamenti, se i due condividono le stesse librerie, cioè le stesse directory su un'unità condivisa, l'aggiornamento può ancora causare problemi, anche se l'altra istanza di R si trova su un'altra macchina . Quindi, uno potrebbe accidentalmente uccidere un processo R e nemmeno vederlo.

risposta

3

La mia forte ipotesi è che non c'è modo di aggirare questo.

Soprattutto quando un pacchetto include codice compilato non è possibile rimuovere e sostituire la DLL mentre è in uso e si aspetta che funzioni ancora. Tutti i puntatori nella DLL utilizzata dalle chiamate R a quelle funzioni richiedono una particolare posizione di memoria e la trovano inspiegabilmente sparita. (Nota - mentre io uso il termine "DLL" qui, intendo in senso non specifico di Windows, in quanto viene utilizzato, ad esempio, nel file di aiuto per ?getLoadedDLLs. "Libreria condivisa" è forse il termine generico migliore .)

(Alcuni conferma dei miei sospetti viene da the R for Windows FAQ, che riferisce che 'le serrature di Windows DLL di [un] pacchetto mentre viene caricato' che può causare update.packages() a fallire.)

io non sono sicuro esattamente come Il meccanismo a carico lento di R è implementato, ma immagina che anche questo possa essere incasinato rimuovendo gli oggetti che si aspetta di trovare in determinati indirizzi nella macchina.

qualcun altro che sa di più sui componenti dei computer sarà sicuramente dare una risposta migliore di questa, ma questi sono i miei pensieri.

+0

Si tratta di un punto importante. Sospetto che il problema di una libreria condivisa sia un problema tra i sistemi operativi. Per la maggior parte dell'uso, sono incline a credere che questo uccida l'idea di hotswapping. Il caso più stretto sarebbe per i pacchetti che non utilizzano librerie condivise esterne, ma non sono sicuro di come funzioni per i pacchetti interamente in R. – Iterator

+0

Penso che la tua risposta schiaccerà il sogno di hotswapping in generale. Anche se ho un pacchetto R puro che mi piacerebbe fare il hotswap, non è una buona pratica presumere di poterlo fare. Vincent ha un risposta ragionevole per come si può fare il controllo delle versioni, piuttosto che lo scambio, che dovrò adattare un po ', ma è chiaro che questo è l'unico modo per aggirare i conflitti hai sottolineato. – Iterator

4

In un ambiente di produzione, probabilmente vuole mantenere almeno due versioni, l'attuale e il precedente, al fine di essere in grado di passare rapidamente indietro al vecchio in caso di problemi. Nulla sarebbe stato sovrascritto o cancellato. È più facile farlo per l'intero ecosistema R: avresti diverse directory, diciamo "R-2.14.1-2011-12-22", "R-2.14.1-2012-01-27", ecc., ognuno contenente tutto (gli eseguibili R e tutti i pacchetti). Queste directory non verrebbero mai aggiornate: se è necessario un aggiornamento, verrà creata una nuova directory. (Alcuni file system forniscono "istantanee" che consentono di avere molte directory molto simili senza eccessivo utilizzo dello spazio.)

Il passaggio da una versione all'altra può essere effettuato sul lato utente, quando gli utenti lanciano R, o sostituendo l'eseguibile R con uno script che userebbe la versione corretta o impostando la loro variabile d'ambiente PATH in modo che punti alla versione desiderata. Ciò garantisce che una determinata sessione veda sempre la stessa versione di tutto.

+0

Questo è un buon suggerimento, sia per la capacità di ripristinare/"annullare" le modifiche e la capacità di riprodurre i risultati. Devo pensarci un po 'più a proposito del sovraccarico di comunicare le informazioni sulla versione. – Iterator

+0

Penso che tu abbia dato un'ottima risposta alle migliori pratiche. La risposta di Josh è più focalizzata sul motivo per cui non esiste un metodo sicuro per lo scambio di hot spot. Sulla base della sua risposta, che ho selezionato, direi che la risposta risponde a ciò che dovrebbe essere fatto per affrontare tali problemi. – Iterator

1

Ecco uno scenario che ho incontrato ieri su Windows 7.

  1. Sono in esecuzione una sessione di R.
  2. Aprire il PDF di un manuale pacchetto.
  3. Chiudere tutte le sessioni R. Dimentica di chiudere il PDF del manuale del pacchetto.
  4. Aprire una nuova istanza di R, update.packages run()

L'installazione non riesce, naturalmente, perché Windows ha ancora il pdf aperto e non può sovrascrivere ....

+0

+1 Sarebbe piuttosto brutto in un ambiente condiviso. Non ho testato sotto Linux con più utenti, ma mi chiedo come possa funzionare per una situazione con, ad esempio, 100 utenti e qualcuno sta leggendo un pacchetto vignetta ... – Iterator

+0

Su Linux, questo non pone alcun problema: per impostazione predefinita, i file in uso non sono bloccati. Se il file PDF è ancora lì dopo l'aggiornamento, il visualizzatore PDF noterebbe la modifica, aggiorna e visualizza quello nuovo. Se il PDF file non è più lì, il visualizzatore PDF probabilmente continuerà a visualizzare quello vecchio (il file non è realmente cancellato, è in uno stato limbo, ancora lì, senza nome, e sarà davvero solo scomparire quando tutte le applicazioni che lo leggono chiudono il file). Nel peggiore dei casi, il visualizzatore PDF mostrerebbe un messaggio di errore, ma non impedirebbe l'aggiornamento. –

Problemi correlati