es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

La llamada de Rscript al esclavo no se cierra correctamente.

Tengo un “Desktop Entry” que llama a una aplicación “shiny”.

Aquí está mi “desktop entry”:

[Desktop Entry]
Type=Application
Comment=App
Name=App
Exec=/usr/bin/Rscript -e "shiny::runApp('~/raspberry_IP/app.R', launch.browser=TRUE)"
Icon=/home/path/to/logo/rpi_logo.png
Terminal=false
Categories=Utility
StartupNotify=true

Esto funciona bien y la aplicación “Shiny” funciona como se espera. Sin embargo, cuando cierro la pestaña del navegador, veo que el proceso sigue ejecutándose.

Estoy ejecutando esta aplicación desde Ubuntu 20.04 LTS.

Si cambio Terminal=false a Terminal=true, veo que la salida de mi terminal se congela (la aplicación ya no se actualiza, por lo que no se imprime ningún diagnóstico). Pero el terminal sigue activo (lo cual tiene sentido dado que el proceso sigue ejecutándose). Puedo presionar CTRL+C para salir de él y detenerlo desde mi terminal, pero ese no es el comportamiento deseado por el usuario.

Veo algunas estrategias para detener la aplicación utilizando stopApp() como se muestra aquí. Esta estrategia utiliza un botón de acción separado para detener la aplicación, por lo que el usuario tiene que detenerla “manualmente”. Esto podría funcionar, pero creo que es natural para el usuario intentar cerrar la pestaña o el navegador (y no hay forma de que sepan que el proceso aún se está ejecutando a menos que lo verifiquen).

Usar esto en el lado del server, sí detiene el proceso, pero no se recomienda (ver aquí).

session$onSessionEnded(stopApp)

En este caso, como mi aplicación se ejecuta en una máquina local, creo que podría salirme con la suya (solo hay un usuario a la vez), pero me preguntaba si hay una mejor práctica para implementar.

Tags:  ,

Answer

  1. Avatar for davy.ai

    Un enfoque para detener el proceso de la aplicación Shiny cuando el usuario cierra la pestaña o ventana del navegador es utilizar el evento beforeUnload en JavaScript para activar un mensaje al lado del servidor y detener la aplicación correctamente. Esto se puede hacer agregando código al archivo app.R para manejar el mensaje y detener la aplicación.

    Aquí hay un ejemplo de fragmento de código para el lado del servidor:

    # Definir una función para detener la aplicación correctamente
    stop_app <- function() {
      message("Deteniendo la aplicación Shiny...")
      shiny::stopApp()
    }
    
    # Definir una función servidor de Shiny
    server <- function(input, output, session) {
    
      # Registrar un evento para el evento "beforeunload"
      session$onSessionEnded(function() {
        stop_app()
      })
    
      # ... Otra lógica del servidor ...
    }
    

    Esto escuchará el evento beforeUnload en el lado del navegador y activará el evento onSessionEnded en Shiny, el cual a su vez llama a la función stop_app para detener la aplicación correctamente.

    En el lado del navegador, agregue este fragmento de código JavaScript al archivo app.R para capturar el evento beforeUnload:

    # Agregue este fragmento de código al archivo ui.R
    tags$script("
      window.addEventListener('beforeunload', function(e) {
        e.preventDefault();
        e.returnValue = '';
        Shiny.onInputChange('stopApp', true);
      });
    ")
    

    Esto activará el evento onInputChange en Shiny, el cual se puede manejar en el lado del servidor para detener la aplicación correctamente.

    # Agregue esto al archivo server.R
    observeEvent(input$stopApp, {
      if (input$stopApp) {
        stop_app()
      }
    }, ignoreNULL = FALSE)
    

    Este enfoque permite que el usuario cierre la pestaña o ventana del navegador sin preocuparse de dejar el proceso de la aplicación Shiny en segundo plano. La aplicación se detendrá correctamente sin ninguna intervención manual del usuario.

Comments are closed.