Rework some things to prepare for the cleanup of old diagrams
This commit is contained in:
parent
c4c6859846
commit
0461b59150
|
|
@ -1,61 +1,14 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/tomwright/lifetime"
|
||||||
"github.com/tomwright/mermaid-server/internal"
|
"github.com/tomwright/mermaid-server/internal"
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
var testInput = []byte(`
|
|
||||||
graph TB
|
|
||||||
|
|
||||||
subgraph "Jira"
|
|
||||||
createTicket["Create ticket"]
|
|
||||||
updateTicket["Update ticket"]
|
|
||||||
fireWebhook["Fire webhook"]
|
|
||||||
|
|
||||||
createTicket-->fireWebhook
|
|
||||||
updateTicket-->fireWebhook
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "Jira Webhook"
|
|
||||||
receiveWebhook["Receive webhook"]
|
|
||||||
storeEvent["Store event in immutable list"]
|
|
||||||
publishNewStoredEventEvent["Publish message to notify system of new event"]
|
|
||||||
|
|
||||||
createEvent["Create internal event that will be stored"]
|
|
||||||
setCreatedAt["Set created at date to now"]
|
|
||||||
setSourceJira["Set source to Jira webhook"]
|
|
||||||
|
|
||||||
receiveWebhook-->createEvent-->setCreatedAt-->setSourceJira-->storeEvent
|
|
||||||
storeEvent-->publishNewStoredEventEvent
|
|
||||||
end
|
|
||||||
|
|
||||||
fireWebhook-->receiveWebhook
|
|
||||||
|
|
||||||
subgraph "Play Event"
|
|
||||||
publishEventUpdated["Publish message to notify system of new status"]
|
|
||||||
|
|
||||||
verifyEventSource["Verify event source"]
|
|
||||||
parsePayload["Parse event payload using source to determine structure"]
|
|
||||||
findEventHandler["Find the handler for the specific event type + version"]
|
|
||||||
getLatestPersistedState["Get latest persisted state"]
|
|
||||||
changeInMemoryStateUsingEventData["Change in-memory state using event data"]
|
|
||||||
persistUpdatedState["Persist updated state"]
|
|
||||||
|
|
||||||
verifyEventSource-->parsePayload
|
|
||||||
parsePayload-->findEventHandler
|
|
||||||
findEventHandler-->getLatestPersistedState-->changeInMemoryStateUsingEventData-->persistUpdatedState
|
|
||||||
|
|
||||||
persistUpdatedState-->publishEventUpdated
|
|
||||||
end
|
|
||||||
|
|
||||||
publishNewStoredEventEvent-->verifyEventSource
|
|
||||||
`)
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
mermaid := flag.String("mermaid", "", "The full path to the mermaidcli executable.")
|
mermaid := flag.String("mermaid", "", "The full path to the mermaidcli executable.")
|
||||||
in := flag.String("in", "", "Directory to store input files.")
|
in := flag.String("in", "", "Directory to store input files.")
|
||||||
|
|
@ -81,20 +34,16 @@ func main() {
|
||||||
cache := internal.NewDiagramCache()
|
cache := internal.NewDiagramCache()
|
||||||
generator := internal.NewGenerator(cache, *mermaid, *in, *out, *puppeteer)
|
generator := internal.NewGenerator(cache, *mermaid, *in, *out, *puppeteer)
|
||||||
|
|
||||||
httpHandler := internal.GenerateHTTPHandler(generator)
|
httpService := internal.NewHTTPService(generator)
|
||||||
|
cleanupService := internal.NewCleanupService(generator)
|
||||||
|
|
||||||
r := http.NewServeMux()
|
lt := lifetime.New(context.Background()).Init()
|
||||||
r.Handle("/generate", http.HandlerFunc(httpHandler))
|
|
||||||
|
|
||||||
httpServer := &http.Server{
|
// Start the http service.
|
||||||
Addr: ":80",
|
lt.Start(httpService)
|
||||||
Handler: r,
|
// Start the cleanup service.
|
||||||
}
|
lt.Start(cleanupService)
|
||||||
log.Printf("Listening on address %s", httpServer.Addr)
|
|
||||||
if err := httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
|
||||||
log.Printf("Could not listen for http connections: %s", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("Shutdown")
|
// Wait for all routines to stop running.
|
||||||
|
lt.Wait()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2
go.mod
2
go.mod
|
|
@ -1,3 +1,5 @@
|
||||||
module github.com/tomwright/mermaid-server
|
module github.com/tomwright/mermaid-server
|
||||||
|
|
||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
|
require github.com/tomwright/lifetime v1.0.0
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
github.com/tomwright/lifetime v1.0.0 h1:Yzj+Td38eUUdZ1ewvOegywFBmKyaCh+8HjKBmeXw6OM=
|
||||||
|
github.com/tomwright/lifetime v1.0.0/go.mod h1:GUCHgRaR/zStvtJiOd3B4gIZayeiz3TgApC9kNYAOQI=
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewCleanupService returns a service that can be used cleanup old diagrams.
|
||||||
|
func NewCleanupService(generator Generator) *cleanupService {
|
||||||
|
return &cleanupService{
|
||||||
|
generator: generator,
|
||||||
|
stopCh: make(chan struct{}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// cleanupService is a service that can be used cleanup old diagrams.
|
||||||
|
type cleanupService struct {
|
||||||
|
generator Generator
|
||||||
|
stopCh chan struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start starts the cleanup service.
|
||||||
|
func (s *cleanupService) Start() error {
|
||||||
|
for {
|
||||||
|
if err := s.generator.CleanUp(time.Hour); err != nil {
|
||||||
|
log.Printf("error when cleaning up: %s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-time.After(time.Minute * 5):
|
||||||
|
continue
|
||||||
|
case <-s.stopCh:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop stops the cleanup service.
|
||||||
|
func (s *cleanupService) Stop() {
|
||||||
|
close(s.stopCh)
|
||||||
|
}
|
||||||
|
|
@ -8,14 +8,18 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Generator provides the ability to generate a diagram.
|
// Generator provides the ability to generate a diagram.
|
||||||
type Generator interface {
|
type Generator interface {
|
||||||
// Generate generates the given diagram.
|
// Generate generates the given diagram.
|
||||||
Generate(diagram *Diagram) error
|
Generate(diagram *Diagram) error
|
||||||
|
// CleanUp removes any diagrams that haven't used within the given duration.
|
||||||
|
CleanUp(duration time.Duration) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewGenerator returns a generator that can be used to generate diagrams.
|
||||||
func NewGenerator(cache DiagramCache, mermaidCLIPath string, inPath string, outPath string, puppeteerConfigPath string) Generator {
|
func NewGenerator(cache DiagramCache, mermaidCLIPath string, inPath string, outPath string, puppeteerConfigPath string) Generator {
|
||||||
return &cachingGenerator{
|
return &cachingGenerator{
|
||||||
cache: cache,
|
cache: cache,
|
||||||
|
|
@ -102,3 +106,9 @@ func (c cachingGenerator) generate(diagram *Diagram) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CleanUp removes any diagrams that haven't used within the given duration.
|
||||||
|
func (c cachingGenerator) CleanUp(duration time.Duration) error {
|
||||||
|
// todo : loop through all cached diagrams and delete any that haven't been used within duration.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -80,8 +80,8 @@ func getDiagramFromPOST(rw http.ResponseWriter, r *http.Request) *Diagram {
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateHTTPHandler returns a HTTP handler used to generate a diagram.
|
// generateHTTPHandler returns a HTTP handler used to generate a diagram.
|
||||||
func GenerateHTTPHandler(generator Generator) func(rw http.ResponseWriter, r *http.Request) {
|
func generateHTTPHandler(generator Generator) func(rw http.ResponseWriter, r *http.Request) {
|
||||||
return func(rw http.ResponseWriter, r *http.Request) {
|
return func(rw http.ResponseWriter, r *http.Request) {
|
||||||
var diagram *Diagram
|
var diagram *Diagram
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewHTTPService returns a service that can be used to start a http server
|
||||||
|
// that will generate diagrams.
|
||||||
|
func NewHTTPService(generator Generator) *httpService {
|
||||||
|
return &httpService{
|
||||||
|
generator: generator,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// httpService is a service that can be used to start a http server
|
||||||
|
// that will generate diagrams.
|
||||||
|
type httpService struct {
|
||||||
|
httpServer *http.Server
|
||||||
|
generator Generator
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start starts the HTTP server.
|
||||||
|
func (s *httpService) Start() error {
|
||||||
|
httpHandler := generateHTTPHandler(s.generator)
|
||||||
|
|
||||||
|
r := http.NewServeMux()
|
||||||
|
r.Handle("/generate", http.HandlerFunc(httpHandler))
|
||||||
|
|
||||||
|
s.httpServer = &http.Server{
|
||||||
|
Addr: ":80",
|
||||||
|
Handler: r,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||||
|
if err != http.ErrServerClosed {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *httpService) Stop() {
|
||||||
|
if s != nil {
|
||||||
|
_ = s.httpServer.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue