Brilhante: ajuste de desempenho com futuro / promessas – a prática

cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br


A segunda parte de nossa série de blogs sobre o Shiny abordou a otimização dentro de aplicativos Shiny. Nós olhou no parte teórica sobre quão brilhante e a pacotes futuros / promessas trabalhos. No contexto dase Em dois pacotes, foi apresentado como eles podem ser usados ​​para terceirizar tarefas complexas para processos secundários, implementando um fluxo de trabalho assíncrono para manter o aplicativo acessível a todos os outros usuários que acessam em paralelo. O pano de fundo para isso é fornecido pela maneira como o Shiny trabalha, no qual essa tarefa pode garantir que não apenas o usuário atual, mas Além disso vários usuários ao mesmo tempo tem que aguarde a conclusão da tarefa. Alguns exemplos dessas tarefas, que chamamos de tarefas de “bloqueio de processo”, serão implementados neste artigo de um exemplo de aplicativo com futuro / promessas. Aqui, a transferência da teoria para a prática será mostrada. Inicialmente, uma visão geral do final aplicativo e sua funcionalidade será fornecida. Posteriormente, exemplos de código selecionados são usados ​​para mostrar como os processos podem ser programados no contexto da sintaxe do futuro / promessas.

Deseja experimentar os procedimentos explicados aqui diretamente com o aplicativo? Aqui você pode encontrar o código!

  1. Info-PID: TO ID do processo atual do processo R ao qual o usuário está conectado pode ser lido aqui.
  2. Starefa torta: Para testar a implementação, complexos e processoAs tarefas de bloqueio podem ser iniciadas aqui. Esses incluem:
    • Carregando um arquivo CSV com 1.500.000 linhas.
    • Encerrando o processo por 10 segundos.
    • O cálculo de um modelo de regressão linear com base em dois vetores com 5.000.000 de entradas cada.
  3. UMAteste de disponibilidade: EuPode ser testado se o processo atual é responsivo ou bloqueado pela execução de uma tarefa. A disponibilidade do R global processo executando o Shiny umapp se distingue da sessão do usuário individual (a distinção será interessante para testar posteriormente).
  4. “Viver” tpergunte: UMA tarefa digitando o número de pontos de dados pode ser iniciado aqui. isto exibirá o resultadoeuive “na trama abaixo. Em conexão com o ponto 2, isso é usado apenas para apresentar diferentes possibilidades de implementação do fluxo de trabalho assíncrono.
  5. Cplano de mudança: Aqui você pode alterar o plano atual de um fluxo de trabalho sequencial para assíncrono (multisessão). Dessa forma, uma avaliação do comportamento do aplicativo a respeito de ambas as possibilidades são possível.
  6. Euinformações / resultados: TAs tarefas iniciadas no ponto 2 podem ser visualizadas e redefinidas. Além disso, informações sobre o plano atual e o status das tarefas podem ser encontradas aqui.

Os componentes – Como o fluxo de trabalho assíncrono é implementado?

Bloco de código # 1

Para entender a funcionalidade do aplicativo e o uso associado de futuras / promessas, a estrutura do aplicativo agora está descrita de usando trechos de código.

No início, os pacotes necessários são adicionados. Euneste exemplo multisessão to plano inicial para o aplicativo está definido Eun linha 10. Isso significa que os blocos de código implementados com futuras / promessas são executados de forma assíncrona por padrão. Nas linhas 12 a 15, são inicializadas duas variáveis ​​reativas, que contêm o plano atual e um dos números aleatórios para o teste de disponibilidade. Como a definição aqui é feita no global.R (ou seja, fora do servidor), as variáveis ​​são válidas para todos os usuários conectados ao processo R.

cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br

Por outro lado, variáveis ​​reativas adicionais são definidas no servidor, que são, portanto, específicas da sessão, ou seja, são criadas individualmente para cada usuário no início de uma sessão.

1library(shiny)
2library(future)
3library(promises)
4library(dplyr)

10plan(multisession)
11
12reac
13plan = "Multisession",
14random_number = round(runif(1, min = 1000, max = 9999))
15)

Bloco de código # 2

As variáveis ​​específicas da sessão contêm o segundo número aleatório do teste de disponibilidade, além de informações e resultados das tarefas atuais / concluídas.

Com base nas definições necessárias, agora você pode começar com a primeira tarefa da implementação: carregando o arquivo CSV.

1function(input, output, session)}
2
3reac_sess
4random_number = round(runif(1, min = 1000, max = 9999)),
5active_task = FALSE,
6current_task = "task_null",
7dataset = NULL,
8model = NULL
9)

Bloco de código # 3

Nas linhas 65 e 66, uma barra de progresso é criada e começou. Isso também mostra ao usuário o status da tarefa.

Atenção: Como as tarefas são executadas em um R separado processo, a função withProgress fornecido pela Shiny não pode ser usado.

Nas linhas 68 – 71, a importação do arquivo CSV é iniciada como um processo assíncrono. Com futuro({Bloco de código }) a execução do código é trocada para outro R processo, de acordo com o plano que selecionamos no início. A saída do console na linha 70 é usada para rastrear o código, isto é, qual ID do processo executou o código. As linhas 72 – 77 definem o que acontece quando a execução é concluída. Nesse caso, o operador de tubulação%…>% do pacote promessas na linha 71 é importante. isto garante que o bloco de código subsequente não seja executado até que a tarefa assíncrona seja concluída com êxito.

Finalmente exclui a barra de progresso, independentemente de os comandos terem sido bem-sucedidos anteriormente. A limpeza da barra de progresso é necessária se o bloco assíncrono anterior não puder ser concluído com êxito. Portanto, esse bloco também é adicionado ao final da cadeia de código com o habitual %>% pipe.


63.observeEvent(input$task_loaddata, {
64
65p
66p$set(value = 0.5, message = "Load Dataset")
67
68future({
69cat(paste0("--- Executed task 'Loading dataset' under PID: ", Sys.getpid(), "n"))
70read.csv("1500000 Sales Records.csv")
71}) %...>%
72{
73reac_sess$dataset
74reac_sess$current_task
75reac_sess&active_task
76cat(paste0("--- Finished task 'Loading dataset' under PID: ", Sys.getpid(), "n"))
77} %>%
78finally(~p$close())

79})

Depois de implementar a primeira tarefa assíncrona, ela pode ser testada diretamente. Isso deve resultar no seguinte comportamento do aplicativo:

Bloco de código # 4

Leia Também  Um mergulho profundo no glmnet: type.gaussian

As linhas 81 – 102 contêm a implementação para encerrar o processo por dez segundos. Inicialmente, essa implementação é executada de forma idêntica ao carregamento do registro de dados. O ajuste da barra de progresso na linha 89, após cinco segundos de parada, deve ser enfatizado. Geralmente, é necessário ter uma visão geral da tarefa no processo principal, mesmo enquanto a tarefa iniciada de forma assíncrona está sendo executada. Também deve ser possível fazer alterações, como ajustar a barra de progresso. Essas alterações geralmente devem ser feitas fora do ambiente futuro, porque sem pacotes adicionais, como ipc, a comunicação entre os vários processos não é possível.


81observeEvent(input$task_sleep, {
82
83p
84p$set(value = 0.1, message = "Begin Sleeping")
85
86future({
87Sys.sleep(5)
88}) %...>%
89{ p$set(value = 0.6, message = "Slept for 5 seconds") } %...>%
90{
91future({
92Sys.sleep(5)
93cat(paste0("--- Executed task 'Sleeping' under PID: ", Sys.getpid(), "n"))

94})
95} %...>%
96{
97reac_sess$current_task
98reac_sess$active_task
99cat(paste0("--- Finished task 'Sleeping' under PID: ", Sys.getpid(), "nn"))
100} %>%
101finally(~p$close())
102})

Bloco de código # 5

Nas linhas 11 – 19 e 173 – 180 a tarefa ao vivo é implementada. Isso mostra outro método de usar o fluxo de trabalho assíncrono. Nas linhas 11 a 19, o conjunto de dados para o gráfico é armazenado como uma variável reativa, na qual a criação do conjunto de dados inicia como um processo assíncrono. Nas linhas 173 – 180, o conjunto de dados pode finalmente ser recuperado e desenhado. EuÉ importante que a variável reativa plot_df não contém o conjunto de dados. Contudo, o objeto futuro tem para contê-lo, pois é responsável pela criação do conjunto de dados. Portanto, o processo de desenho deve ser adicionado ao conjunto de dados com um promessa-pipe (% …>%). Enquanto o conjunto de dados é criado e desenhado “ao vivo”, o mesmo comportamento deve ocorrer como quando o arquivo CSV é carregado de forma assíncrona.

O fluxo de trabalho assíncrono pode ser implementado de várias outras maneiras, por exemplo, o futuro bloco do último bloco de código pode ser implementado diretamente no renderPlot({…}) meio Ambiente. Além disso, os resultados dos futuros blocos podem ser gerenciados de várias maneiras diferentes (por exemplo, tratamento de erros para tarefas com falha / instruções de função explícitas para tarefas bem-sucedidas com então( … )).


11plot_df
12boné
13
14future({
15x
16y
17data.frame("x" = x, "y" = y)
18})
19})

173output$number_plot
174plotdf() %...>%
175{
176df
177ggplot(df, aes(x = x, y = y)) +
178geom_point()
179}
180})

Conclusão

Mesmo que a implementação de tarefas com promessas futuras atenda apenas a um aspecto específico da otimização de aplicativos Shiny, isso pode contribuir significativamente para o aumento da satisfação da experiência do usuário (UX). Os pontos de otimização mostrados acima mostram seus pontos fortes quando muitos usuários trabalham no aplicativo ao mesmo tempo. Se forem necessários processos individuais, como acesso a bancos de dados, renderização de gráficos, otimização da importação de dados para seu tempo de execução, um pacote completo poderá ser montado em cooperação com o fluxo de trabalho assíncrono e o recurso de armazenamento horizontal. Isso combina as amplas possibilidades de aplicativos Shiny com as demandas modernas de desempenho e facilidade de uso.

Você tem problemas com o desempenho de seus aplicativos Shiny? Estamos felizes em ajudá-lo com a concepção de seus aplicativos, desde o design inicial até a otimização de desempenho das infraestruturas e aplicativos existentes. Contate-Nos!

Leia Também  HBUS seleciona Onfido como seu provedor de verificação de identidade para melhor integração do cliente



cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br