Shiny R reactivevalues内存泄漏

时间:2015-06-13 11:55:17

标签: r shiny reactive-programming

我试图理解为什么骑自行车使用闪亮的reactivevalues会导致它使用更多内存。上下文是一个用户界面,可以选择自动执行给定策略。以下示例基于圣彼得堡悖论。我理解将整个自动化过程放在一个单独的函数文件中可能是更好的做法,但我想了解为什么反应对象的大小增加以及是否有更直接的解决方法。

下面的示例将打印出磁盘上正在使用的内存量values。保存到列表的大小没有增加。

library(shiny)
library(pryr)


server=shinyServer(function(input, output) {

  values=reactiveValues(win=0,
                        total=1000,
                        gamble=0,
                        stick=0,
                        outcome=0,
                        auto.counter=0
                        )


  #############################################
  # update action from buttons
  observe({
    if(!is.null(input$stick)){
      isolate({
      values$stick=values$stick+1
      })
    }
  })

  observe({
    if(!is.null(input$gamble)){
      isolate({
        values$gamble=values$gamble+1
      })
    }
  })

  #############################################
  ## perform stick action
  observe({
    if(values$stick>0){
      isolate({
        values$total=values$total+2^values$win
        values$auto.counter=max(values$auto.counter-1,0)
        values$win=0
        cat("\nStick:",2^values$win)
        cat("\nReactive values size:",object_size(values))
      })
    }
  })
  # perform gamble action
  observe({
    if(values$gamble>0){
    isolate({
      values$outcome=sample(1:2,1)
      if(values$win==0){
        values$total=values$total-input$entry
      }
      if(values$outcome==1){
        output$print=renderText("Win")
        values$win=values$win+1
      } else {
        output$print=renderText("Lose")
        values$win=0
      }
      cat("\nGamble:",2^values$win)
      cat("\nReactive values size:",object_size(values))
      values$auto.counter=max(values$auto.counter-1,0)

    })
    }
  })

  #############################################
  # automation input
  observe({
    if(input$automate>0){
      isolate({
        values$auto.counter=input$rep
      })
    }
  })

  # if automation on run until auto.counter==0
  observe({
    if(!is.null(values$auto.counter)){
      if(values$auto.counter>0){
        isolate({
          if(2^values$win>input$target){
            values$stick=values$stick+1
          } else {
            values$gamble=values$gamble+1
          }
        })
      }
    }
  })
  #############################################
  # render views
  output$total=renderText({paste("Total winnings:",values$total)})
  output$currentvalue=renderText({paste("Current jackpot:",2^values$win)})
})


ui=shinyUI(fluidPage(

  br(),
  fluidRow(
    column(
      4,
      numericInput(inputId="entry",label="Entry Fee",value=10),
      actionButton(inputId="gamble",label='Gamble'),
      actionButton(inputId="stick",label='Stick'),
      h4("Automate"),
      numericInput(inputId="target",label="Target value",value=20),
      numericInput(inputId="rep",label="Turns",value=10),
      actionButton(inputId="automate",label='Automate')
    ),
    column(
      8,
      textOutput("currentvalue"),
      textOutput("total"),
      textOutput("print")
      )
  )
))


runApp(list(ui=ui,server=server))

0 个答案:

没有答案