From 206032be6e99038b54313cfca42074baa17656d1 Mon Sep 17 00:00:00 2001 From: Stephen Searles Date: Tue, 13 Jun 2017 22:54:42 -0700 Subject: [PATCH] document saving to file plus goroutine cleanup --- caddyhugo.go | 69 ++++++++++++++++++++++++++++++++++++++--------- templates.go | 2 +- testdir/caddyfile | 1 + 3 files changed, 59 insertions(+), 13 deletions(-) diff --git a/caddyhugo.go b/caddyhugo.go index 028464c..a6ee1b4 100644 --- a/caddyhugo.go +++ b/caddyhugo.go @@ -12,6 +12,7 @@ import ( "strings" "sync" "sync/atomic" + "time" "git.stephensearles.com/stephen/acedoc" @@ -32,11 +33,16 @@ func init() { // ... there are others. See the godoc. } +type docref struct { + clients uint + doc *acedoc.Document +} + type CaddyHugo struct { ServerType string Site *httpserver.SiteConfig - Docs map[string]*acedoc.Document + docs map[string]*docref mtx sync.Mutex authorTmpl, adminTmpl, editTmpl *template.Template @@ -61,7 +67,7 @@ func (ch *CaddyHugo) LTime() uint64 { func (ch *CaddyHugo) Setup(c *caddy.Controller) error { - ch.Docs = make(map[string]*acedoc.Document) + ch.docs = make(map[string]*docref) ch.Site = httpserver.GetConfig(c) var err error @@ -165,13 +171,13 @@ func (ch *CaddyHugo) Edit(c *caddy.Controller) httpserver.Handler { return ch.DeltaWebsocket(w, r) } - doc, err := ch.Doc(r) + doc, err := ch.doc(r) if err != nil { fmt.Println(err) return http.StatusNotFound, err } - err = ch.editTmpl.Execute(w, ch.TmplData(r, doc)) + err = ch.editTmpl.Execute(w, ch.TmplData(r, doc.doc)) if err != nil { fmt.Println(err) @@ -182,13 +188,13 @@ func (ch *CaddyHugo) Edit(c *caddy.Controller) httpserver.Handler { }) } -func (ch *CaddyHugo) Doc(r *http.Request) (*acedoc.Document, error) { +func (ch *CaddyHugo) doc(r *http.Request) (*docref, error) { ch.mtx.Lock() defer ch.mtx.Unlock() name := r.URL.Path[len("/hugo/edit/"):] - _, ok := ch.Docs[name] + _, ok := ch.docs[name] if !ok { fmt.Println("opening", name) contents, err := ioutil.ReadFile(name) @@ -196,10 +202,41 @@ func (ch *CaddyHugo) Doc(r *http.Request) (*acedoc.Document, error) { return nil, err } - ch.Docs[name] = acedoc.NewString(string(contents)) + ref := &docref{doc: acedoc.NewString(string(contents))} + ch.docs[name] = ref + + go func() { + ticker := time.NewTicker(1 * time.Minute) + idleMinutes := 0 + + for { + <-ticker.C + ch.mtx.Lock() + + fmt.Println("saving", name) + err := ioutil.WriteFile(name, []byte(ref.doc.Contents()), 0644) + if err != nil { + fmt.Println("error saving document contents:", err) + } + + if ref.clients == 0 { + idleMinutes++ + if idleMinutes > 10 { + fmt.Println("idle for", idleMinutes, "minutes, quitting") + delete(ch.docs, name) + ch.mtx.Unlock() + return + } + fmt.Println("idle for", idleMinutes, "minutes") + } else { + idleMinutes = 0 + } + ch.mtx.Unlock() + } + }() } - return ch.Docs[name], nil + return ch.docs[name], nil } func (ch *CaddyHugo) DeltaWebsocket(w http.ResponseWriter, r *http.Request) (int, error) { @@ -214,21 +251,30 @@ func (ch *CaddyHugo) DeltaWebsocket(w http.ResponseWriter, r *http.Request) (int return http.StatusBadRequest, err } - doc, err := ch.Doc(r) + doc, err := ch.doc(r) if err != nil { fmt.Println(err) return http.StatusBadRequest, err } - client := doc.Client(acedoc.DeltaHandlerFunc(func(ds []acedoc.Delta) error { + client := doc.doc.Client(acedoc.DeltaHandlerFunc(func(ds []acedoc.Delta) error { err := conn.WriteJSON(Message{ Deltas: ds, LTime: ch.LTime(), }) - fmt.Println("here", ds, err) return err })) + ch.mtx.Lock() + doc.clients++ + ch.mtx.Unlock() + + defer func() { + ch.mtx.Lock() + doc.clients-- + ch.mtx.Unlock() + }() + for { var message Message err := conn.ReadJSON(&message) @@ -237,7 +283,6 @@ func (ch *CaddyHugo) DeltaWebsocket(w http.ResponseWriter, r *http.Request) (int } ch.ObserveLTime(message.LTime) - fmt.Println(message) err = client.PushDeltas(message.Deltas...) if err != nil { diff --git a/templates.go b/templates.go index 10a3222..95fe730 100644 --- a/templates.go +++ b/templates.go @@ -107,7 +107,7 @@ var EditPage = ` // Listen for messages socket.addEventListener('message', function (event) { - console.log('Message from server', event.data); + // console.log('Message from server', event.data); var message = JSON.parse(event.data); observe(message.ltime); diff --git a/testdir/caddyfile b/testdir/caddyfile index ffe92de..46e333a 100644 --- a/testdir/caddyfile +++ b/testdir/caddyfile @@ -1,4 +1,5 @@ localhost:8080 { hugo + root ./testsite errors { * } }