document saving to file plus goroutine cleanup

pull/8/head
Stephen Searles 8 years ago
parent 7a498554a0
commit 206032be6e
  1. 69
      caddyhugo.go
  2. 2
      templates.go
  3. 1
      testdir/caddyfile

@ -12,6 +12,7 @@ import (
"strings" "strings"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time"
"git.stephensearles.com/stephen/acedoc" "git.stephensearles.com/stephen/acedoc"
@ -32,11 +33,16 @@ func init() {
// ... there are others. See the godoc. // ... there are others. See the godoc.
} }
type docref struct {
clients uint
doc *acedoc.Document
}
type CaddyHugo struct { type CaddyHugo struct {
ServerType string ServerType string
Site *httpserver.SiteConfig Site *httpserver.SiteConfig
Docs map[string]*acedoc.Document docs map[string]*docref
mtx sync.Mutex mtx sync.Mutex
authorTmpl, adminTmpl, editTmpl *template.Template authorTmpl, adminTmpl, editTmpl *template.Template
@ -61,7 +67,7 @@ func (ch *CaddyHugo) LTime() uint64 {
func (ch *CaddyHugo) Setup(c *caddy.Controller) error { 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) ch.Site = httpserver.GetConfig(c)
var err error var err error
@ -165,13 +171,13 @@ func (ch *CaddyHugo) Edit(c *caddy.Controller) httpserver.Handler {
return ch.DeltaWebsocket(w, r) return ch.DeltaWebsocket(w, r)
} }
doc, err := ch.Doc(r) doc, err := ch.doc(r)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
return http.StatusNotFound, 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 { if err != nil {
fmt.Println(err) 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() ch.mtx.Lock()
defer ch.mtx.Unlock() defer ch.mtx.Unlock()
name := r.URL.Path[len("/hugo/edit/"):] name := r.URL.Path[len("/hugo/edit/"):]
_, ok := ch.Docs[name] _, ok := ch.docs[name]
if !ok { if !ok {
fmt.Println("opening", name) fmt.Println("opening", name)
contents, err := ioutil.ReadFile(name) contents, err := ioutil.ReadFile(name)
@ -196,10 +202,41 @@ func (ch *CaddyHugo) Doc(r *http.Request) (*acedoc.Document, error) {
return nil, err 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)
} }
return ch.Docs[name], nil 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
} }
func (ch *CaddyHugo) DeltaWebsocket(w http.ResponseWriter, r *http.Request) (int, error) { 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 return http.StatusBadRequest, err
} }
doc, err := ch.Doc(r) doc, err := ch.doc(r)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
return http.StatusBadRequest, 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{ err := conn.WriteJSON(Message{
Deltas: ds, Deltas: ds,
LTime: ch.LTime(), LTime: ch.LTime(),
}) })
fmt.Println("here", ds, err)
return err return err
})) }))
ch.mtx.Lock()
doc.clients++
ch.mtx.Unlock()
defer func() {
ch.mtx.Lock()
doc.clients--
ch.mtx.Unlock()
}()
for { for {
var message Message var message Message
err := conn.ReadJSON(&message) err := conn.ReadJSON(&message)
@ -237,7 +283,6 @@ func (ch *CaddyHugo) DeltaWebsocket(w http.ResponseWriter, r *http.Request) (int
} }
ch.ObserveLTime(message.LTime) ch.ObserveLTime(message.LTime)
fmt.Println(message)
err = client.PushDeltas(message.Deltas...) err = client.PushDeltas(message.Deltas...)
if err != nil { if err != nil {

@ -107,7 +107,7 @@ var EditPage = `<html>
// Listen for messages // Listen for messages
socket.addEventListener('message', function (event) { 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); var message = JSON.parse(event.data);
observe(message.ltime); observe(message.ltime);

@ -1,4 +1,5 @@
localhost:8080 { localhost:8080 {
hugo hugo
root ./testsite
errors { * } errors { * }
} }

Loading…
Cancel
Save