using idleshut as a separate package

pull/8/head
Stephen Searles 7 years ago
parent 618574f160
commit 7e4686a229
  1. 75
      client.go
  2. 64
      hugo.go

@ -6,11 +6,11 @@ import (
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"os" "os"
"os/exec"
"path" "path"
"time" "sync"
"git.stephensearles.com/stephen/acedoc" "git.stephensearles.com/stephen/acedoc"
"git.stephensearles.com/stephen/idleshut"
) )
type editSession struct { type editSession struct {
@ -19,6 +19,14 @@ type editSession struct {
filename string filename string
doc *acedoc.Document doc *acedoc.Document
tmpdir string tmpdir string
mtx sync.Mutex
}
func (es *editSession) Clients() uint {
es.mtx.Lock()
defer es.mtx.Unlock()
return es.clients
} }
func (ch *CaddyHugo) newEditSession(docName string) (*editSession, error) { func (ch *CaddyHugo) newEditSession(docName string) (*editSession, error) {
@ -54,68 +62,15 @@ func (ch *CaddyHugo) newEditSession(docName string) (*editSession, error) {
} }
func (ch *CaddyHugo) renderDraft(es *editSession) error { func (ch *CaddyHugo) renderDraft(es *editSession) error {
hugoCmd := exec.Command("hugo", "--watch", "-D", "-d", es.tmpdir) var proc *idleshut.Process
hugoCmd.Dir = ch.Dir
err := hugoCmd.Start()
if err != nil {
return fmt.Errorf("error starting hugo: %v", err)
}
renderer := HugoCmdRenderer{ f := func() {
TmpDir: es.tmpdir, if es.clients != 0 {
SrcDir: ch.Dir, proc.Touch()
Filename: es.filename,
} }
go func() {
ticker := time.NewTicker(WebsocketFileTicker)
idleTicks := 0
closeTicks := int(IdleWebsocketTimeout / WebsocketFileTicker)
defer func() {
err = renderer.Stop()
if err != nil {
fmt.Println("error stopping hugo:", err)
} }
}()
for { proc = idleshut.New(HugoCmdProcessConfig(ch, es, f))
<-ticker.C
ch.mtx.Lock()
// render if there are connected clients OR if we haven't
// been idle for very long.
if es.clients > 0 || idleTicks < 2 {
err := renderer.Render(es.doc.Contents())
if err != nil {
fmt.Println("error saving document contents:", err)
}
}
// count up idle time and possibly close down
if es.clients == 0 {
idleTicks++
if idleTicks >= closeTicks {
idleTime := time.Duration(idleTicks) * WebsocketFileTicker
err := ch.Publish()
fmt.Printf("idle for %v, quitting\n", idleTime)
if err != nil {
fmt.Printf(", error publishing: %v\n", err)
}
es.doc.Close()
os.RemoveAll(es.tmpdir)
delete(ch.docs, es.filename)
ch.mtx.Unlock()
return
}
} else {
idleTicks = 0
}
ch.mtx.Unlock()
}
}()
return nil return nil
} }

@ -5,7 +5,8 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"os/exec" "os/exec"
"sync"
"git.stephensearles.com/stephen/idleshut"
) )
type HugoInteractor interface { type HugoInteractor interface {
@ -13,55 +14,56 @@ type HugoInteractor interface {
} }
type HugoRenderer interface { type HugoRenderer interface {
WriteContent(contents string) error
Start() error Start() error
Stop() error Stop() error
} }
type HugoCmdRenderer struct { func HugoCmdProcessConfig(ch *CaddyHugo, es *editSession, touchFn func()) idleshut.Config {
SrcDir string cmd := exec.Command("hugo", "--watch", "-D", "-d", es.tmpdir)
TmpDir string cmd.Dir = es.tmpdir
Filename string
cmd *exec.Cmd
mtx sync.Mutex
}
func (hcr *HugoCmdRenderer) Render(contents string) error {
err := ioutil.WriteFile(hcr.Filename, []byte(contents), 0644)
return err
}
func (hcr *HugoCmdRenderer) Start() error {
hcr.mtx.Lock()
defer hcr.mtx.Unlock()
hcr.cmd = exec.Command("hugo", "--watch", "-D", "-d", hcr.TmpDir) return idleshut.Config{
hcr.cmd.Dir = hcr.TmpDir Tick: WebsocketFileTicker,
MaxIdleTicks: uint(IdleWebsocketTimeout/WebsocketFileTicker) + 1,
Start: func() error {
err := hcr.cmd.Start() err := cmd.Start()
if err != nil { if err != nil {
return fmt.Errorf("error starting hugo: %v", err) return fmt.Errorf("error starting hugo: %v", err)
} }
return nil return nil
} },
Stop: func() error {
func (hcr *HugoCmdRenderer) Stop() error { if cmd == nil {
hcr.mtx.Lock()
defer hcr.mtx.Unlock()
if hcr.cmd == nil {
return nil return nil
} }
err := hcr.cmd.Process.Signal(os.Interrupt) err := cmd.Process.Signal(os.Interrupt)
if err != nil { if err != nil {
return err return fmt.Errorf("error signalling hugo to stop: %v", err)
} }
err = hcr.cmd.Wait() err = cmd.Wait()
if err != nil { if err != nil {
return fmt.Errorf("error waiting for hugo to stop: %v", err)
return err return err
} }
es.doc.Close()
os.RemoveAll(es.tmpdir)
delete(ch.docs, es.filename)
return nil return nil
},
IdleProcessError: func(err error) {
fmt.Println("error processing draft:", err)
},
IdleTick: func() error {
return ioutil.WriteFile(es.filename, []byte(es.doc.Contents()), 0644)
},
ActiveTick: func() error {
return ioutil.WriteFile(es.filename, []byte(es.doc.Contents()), 0644)
},
}
} }

Loading…
Cancel
Save