document saving to file plus goroutine cleanup
This commit is contained in:
+57
-12
@@ -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)
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
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 {
|
||||||
|
|||||||
+1
-1
@@ -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 { * }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user