Reputation: 5734
Is there a way to remove the whole static directory from the server once its content was served for one time? (with served I mean being displayed on the browser once).
func main() {
fs := http.FileServer(http.Dir(tempDir))
http.Handle("/", fs)
http.HandleFunc("/app/wo", workOrderApp)
log.Fatal(http.ListenAndServe(":"+os.Args[1], nil))
}
func workOrderApp(w http.ResponseWriter, r *http.Request) {
workOrderAppProcess(w)
time.Sleep(time.Duration(4 * time.Second)) //some time to let render the html
os.RemoveAll(tempDir)
}
The sleep os.RemoveAll
was a hit and miss. Had to adjust the sleep time to a few seconds otherwise the file sometimes was served and sometimes not, I believe because bandwith or network related stuff. But it also had the side effect of delaying the whole rendering of the page.
In this example I remove all the directory, which is what I want.
func workOrderAppProcess(aid, date, language, token string, w http.ResponseWriter) {
zipDir := os.Args[2]
if _, err := os.Stat(tempDir); os.IsNotExist(err) {
log.Printf("Creating directory: %v", tempDir)
err := os.MkdirAll(tempDir, 0777)
if err != nil {
log.Print(err.Error())
}
}
log.Printf("Extracting file: %v to: %v", date+".zip", tempDir)
zipPath, _ := filepath.Abs(zipDir + "/" + date + ".zip")
app.ExtractZip(zipPath, tempDir)
batch := app.ReturnBatchNumber(tempDir + date)
typesData := app.ReturnWorkTypeData(app.ParseXML(tempDir + date + "/" + batch + "_type_list.xml"))
record := app.FindAppointmentRecord(aid, app.ParseXML(tempDir+date+"/"+batch+"_appt.xml"))
signatureFileURL := app.ReturnSignatureFileURL(tempDir+date, aid, date)
app.RenderTemplate(record, typesData, "template/wo.html", language, "/"+signatureFileURL, w)
}
Upvotes: 0
Views: 470
Reputation: 79674
Your code is causing the HTTP handler to wait 4 seconds, delete the files, then finalize the HTTP response. Just remove the sleep.
func workOrderApp(w http.ResponseWriter, r *http.Request) {
workOrderAppProcess(w)
os.RemoveAll(tempDir)
}
This is more efficient, more directly reflects your intention, and doesen't leave the HTTP connection open needlessly for an extra 4 seconds.
If you have other logic in your handler not shown, and you want to ensure that the delete happens in all cases, a defer
can be useful:
func workOrderApp(w http.ResponseWriter, r *http.Request) {
workOrderAppProcess(w)
defer os.RemoveAll(tempDir)
/* Other logic that may do things */
}
After discussion in chat, it's apparent that workOrderAppProcess
is rendering your HTML, and that os.RemoveAll
is removing the images needed by that HTML. To solve this, you need to delay the removal, but after serving the HTML. This can be done with a simple goroutine:
func workOrderApp(w http.ResponseWriter, r *http.Request) {
workOrderAppProcess(w)
go func() {
time.Sleep(60 * time.Second)
os.RemoveAll(tempDir)
}()
}
Upvotes: 3