using idleshut as a separate package

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

@ -6,11 +6,11 @@ import (
"io/ioutil"
"net/http"
"os"
"os/exec"
"path"
"time"
"sync"
"git.stephensearles.com/stephen/acedoc"
"git.stephensearles.com/stephen/idleshut"
)
type editSession struct {
@ -19,6 +19,14 @@ type editSession struct {
filename string
doc *acedoc.Document
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) {
@ -54,68 +62,15 @@ func (ch *CaddyHugo) newEditSession(docName string) (*editSession, error) {
}
func (ch *CaddyHugo) renderDraft(es *editSession) error {
hugoCmd := exec.Command("hugo", "--watch", "-D", "-d", es.tmpdir)
hugoCmd.Dir = ch.Dir
err := hugoCmd.Start()
if err != nil {
return fmt.Errorf("error starting hugo: %v", err)
}
var proc *idleshut.Process
renderer := HugoCmdRenderer{
TmpDir: es.tmpdir,
SrcDir: ch.Dir,
Filename: es.filename,
f := func() {
if es.clients != 0 {
proc.Touch()
}
}
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 {
<-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()
}
}()
proc = idleshut.New(HugoCmdProcessConfig(ch, es, f))
return nil
}

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

Loading…
Cancel
Save