Perform multiple actions upon pressing an actionButton

I've been struggling to get my Shiny app to perform multiple operations upon pressing a single actionButton. I've looked around a lot and haven't been able to solve it. I've tried eventReactive, observeEvent, putting everything in one block, separating them out - you can see the eventReactive and observeEvent attempts in the server.R code.

I have a button which is supposed to run some models, once pressed. Upon pressing the button, I'd like to do quite a few things:

  • Print a message letting the user know that something is happening
  • Concatenate the previously-defined user options into a .sh file and execute model prediction
  • Periodically check for the model output file
  • Once output file has been created, print "Done" and save as a global variable for further analysis

This is what I have so far (it doesn't work, the model runs [yay!] and that's it). It's particularly confusing to me that the sys command runs fine, but the "Running" message doesn't get printed. I've made sure that I haven't misspelt any var names.

Dummy python script to produce an output: Let's call it script_shiny.py

import time
import pandas as pd

# construct dummy df
d = {'col1': [1, 2], 'col2': [3, 4], 'col3': [5,6]}
df = pd.DataFrame(data=d)

time.sleep(15) # let's add a delay to simulate the 'real' situation

df.to_csv("test_out.txt",sep="\t") # create the output file to be detected

The relevant part of ui.R:

*CODE TO CAPTURE PARAMS, WORKS FINE*
shiny::actionButton("button", "Run PIDGIN"), # RUN MODELS
tags$br(),
textOutput("pidginrunning"), # OUTPUT RUNNING MESSAGE
textOutput("pidgindone"), # OUTPUT DONE MESSAGE        

The relevant part of server.R:

# One approach - observeEvent and defining renderText and .sh file creation and running all together
observeEvent(input$button, { # OBSERVE BUTTON BEING PRESSED
  output$pidginrunning <- renderText({ # LET USER KNOW ITS RUNNING - NOT WORKING
    paste0("Running PIDGIN...")
  })
   
  # CREATE .SH FILE AND RUN DUMMY SCRIPT - WORKING (params previously defined)
  bin_bash <- "#!/bin/bash"
  output_name <<- "test_out.txt"
  runline <- paste0("python script_shiny.py")
  bash_file <- data.frame(c(bin_bash,runline))
  write.table(bash_file,"./run_pidgin.sh",quote=F,row.names=F,col.names=F)
  system("bash -i run_pidgin.sh")
})

# CHECK OUTPUT - NOT WORKING
# Defining output_name in the previous code block works, its defined as a global variable
# Other approach, use eventReactive to define a 'function' which is called separately
checkOutput <- eventReactive(input$button, {
  reactivePoll(1000, session, checkFunc = function() {
    if (file.exists(output_name)==T) # check for the output file
      assign(x = "preds", # Read it in if so, and define global variable
      value = read.csv(output_name,header=T,sep="\t"),
      envir = .GlobalEnv)
      paste0("Done. Please move onto the Results tab.")
    })
})
output$pidgindone <- renderText({ # PRINT DONE MESSAGE SO USER KNOWS TO MOVE ON
  checkOutput()
})

Cheers for your time and help.