Add remaining code for diagram cleanup
This commit is contained in:
parent
0461b59150
commit
f1f2012a95
|
|
@ -0,0 +1,26 @@
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v*.*.*'
|
||||||
|
name: Build
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
go-version: [1.13.x]
|
||||||
|
platform: [ubuntu-latest]
|
||||||
|
runs-on: ${{ matrix.platform }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
- name: Set env
|
||||||
|
run: echo ::set-env name=RELEASE_VERSION::${GITHUB_REF:10}
|
||||||
|
- name: Build
|
||||||
|
run: docker build
|
||||||
|
-t tomwright/mermaid-server:latest \
|
||||||
|
-t tomwright/mermaid-server:${{ env.RELEASE_VERSION }} \
|
||||||
|
-f Dockerfile .
|
||||||
|
- name: Login
|
||||||
|
run: echo ${{ secrets.DOCKER_PASS }} | docker login -u${{ secrets.DOCKER_USER }} --password-stdin
|
||||||
|
- name: Push
|
||||||
|
run: docker push tomwright/mermaid-server:latest && docker push tomwright/mermaid-server:${{ env.RELEASE_VERSION }}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
on: [push, pull_request]
|
||||||
|
name: Test
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
go-version: [1.13.x]
|
||||||
|
platform: [ubuntu-latest]
|
||||||
|
runs-on: ${{ matrix.platform }}
|
||||||
|
steps:
|
||||||
|
- name: Install Go
|
||||||
|
uses: actions/setup-go@v1
|
||||||
|
with:
|
||||||
|
go-version: ${{ matrix.go-version }}
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
- uses: actions/cache@v1
|
||||||
|
with:
|
||||||
|
path: ~/go/pkg/mod
|
||||||
|
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-go-
|
||||||
|
- name: Test
|
||||||
|
run: go test -race ./...
|
||||||
|
|
@ -10,6 +10,10 @@ type DiagramCache interface {
|
||||||
Has(diagram *Diagram) (bool, error)
|
Has(diagram *Diagram) (bool, error)
|
||||||
// Get returns a cached version of the given diagram description.
|
// Get returns a cached version of the given diagram description.
|
||||||
Get(diagram *Diagram) (*Diagram, error)
|
Get(diagram *Diagram) (*Diagram, error)
|
||||||
|
// GetAll returns all of the cached diagrams.
|
||||||
|
GetAll() ([]*Diagram, error)
|
||||||
|
// Delete deletes a cached version of the given diagram.
|
||||||
|
Delete(diagram *Diagram) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDiagramCache returns an implementation of DiagramCache.
|
// NewDiagramCache returns an implementation of DiagramCache.
|
||||||
|
|
@ -57,3 +61,27 @@ func (c *inMemoryDiagramCache) Get(diagram *Diagram) (*Diagram, error) {
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAll returns all of the cached diagrams.
|
||||||
|
func (c *inMemoryDiagramCache) GetAll() ([]*Diagram, error) {
|
||||||
|
res := make([]*Diagram, len(c.idToDiagram))
|
||||||
|
i := 0
|
||||||
|
for _, diagram := range c.idToDiagram {
|
||||||
|
res[i] = diagram
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete deletes a cached version of the given diagram.
|
||||||
|
func (c *inMemoryDiagramCache) Delete(diagram *Diagram) error {
|
||||||
|
id, err := diagram.ID()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, ok := c.idToDiagram[id]; ok {
|
||||||
|
delete(c.idToDiagram, id)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,22 +5,45 @@ import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewDiagram returns a new diagram.
|
// NewDiagram returns a new diagram.
|
||||||
func NewDiagram(description []byte) *Diagram {
|
func NewDiagram(description []byte) *Diagram {
|
||||||
return &Diagram{
|
return &Diagram{
|
||||||
description: []byte(strings.TrimSpace(string(description))),
|
description: []byte(strings.TrimSpace(string(description))),
|
||||||
|
lastTouched: time.Now(),
|
||||||
|
mu: &sync.RWMutex{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Diagram represents a single diagram.
|
||||||
type Diagram struct {
|
type Diagram struct {
|
||||||
// iD is the ID of the Diagram
|
// id is the ID of the Diagram
|
||||||
id string
|
id string
|
||||||
// description is the description of the diagram.
|
// description is the description of the diagram.
|
||||||
description []byte
|
description []byte
|
||||||
// Output is the filepath to the output file.
|
// Output is the filepath to the output file.
|
||||||
Output string
|
Output string
|
||||||
|
// mu is a mutex to protect the last touched value.
|
||||||
|
mu *sync.RWMutex
|
||||||
|
// lastTouched is the time that the diagram was last used.
|
||||||
|
lastTouched time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
// Touch updates the last touched time of the diagram.
|
||||||
|
func (d *Diagram) Touch() {
|
||||||
|
d.mu.Lock()
|
||||||
|
defer d.mu.Unlock()
|
||||||
|
d.lastTouched = time.Now()
|
||||||
|
}
|
||||||
|
|
||||||
|
// TouchedInDuration returns true if the diagram has been touched in the given duration.
|
||||||
|
func (d *Diagram) TouchedInDuration(duration time.Duration) bool {
|
||||||
|
d.mu.Lock()
|
||||||
|
defer d.mu.Unlock()
|
||||||
|
return time.Now().Add(-duration).Before(d.lastTouched)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ID returns an ID for the diagram.
|
// ID returns an ID for the diagram.
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,17 @@ func (c cachingGenerator) Generate(diagram *Diagram) error {
|
||||||
return fmt.Errorf("cache.Get failed: %w", err)
|
return fmt.Errorf("cache.Get failed: %w", err)
|
||||||
}
|
}
|
||||||
*diagram = *cached
|
*diagram = *cached
|
||||||
|
|
||||||
|
// Update diagram last touched date
|
||||||
|
diagram.Touch()
|
||||||
|
if err := c.cache.Store(diagram); err != nil {
|
||||||
|
return fmt.Errorf("cache.Store failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
diagram.Touch()
|
||||||
if err := c.generate(diagram); err != nil {
|
if err := c.generate(diagram); err != nil {
|
||||||
return fmt.Errorf("cachingGenerater.generate failed: %w", err)
|
return fmt.Errorf("cachingGenerater.generate failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
@ -109,6 +118,38 @@ func (c cachingGenerator) generate(diagram *Diagram) error {
|
||||||
|
|
||||||
// CleanUp removes any diagrams that haven't used within the given duration.
|
// CleanUp removes any diagrams that haven't used within the given duration.
|
||||||
func (c cachingGenerator) CleanUp(duration time.Duration) error {
|
func (c cachingGenerator) CleanUp(duration time.Duration) error {
|
||||||
// todo : loop through all cached diagrams and delete any that haven't been used within duration.
|
diagrams, err := c.cache.GetAll()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not get cached diagrams: %w", err)
|
||||||
|
}
|
||||||
|
for _, d := range diagrams {
|
||||||
|
if !d.TouchedInDuration(duration) {
|
||||||
|
if err := c.delete(d); err != nil {
|
||||||
|
return fmt.Errorf("could not delete diagram: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete removes any diagrams that haven't used within the given duration.
|
||||||
|
func (c cachingGenerator) delete(diagram *Diagram) error {
|
||||||
|
id, err := diagram.ID()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot get diagram ID: %w", err)
|
||||||
|
}
|
||||||
|
inPath := fmt.Sprintf("%s/%s.mmd", c.inPath, id)
|
||||||
|
outPath := fmt.Sprintf("%s/%s.svg", c.outPath, id)
|
||||||
|
|
||||||
|
if err := os.Remove(inPath); err != nil {
|
||||||
|
return fmt.Errorf("could not delete diagram input: %w", err)
|
||||||
|
}
|
||||||
|
if err := os.Remove(outPath); err != nil {
|
||||||
|
return fmt.Errorf("could not delete diagram output: %w", err)
|
||||||
|
}
|
||||||
|
if err := c.cache.Delete(diagram); err != nil {
|
||||||
|
return fmt.Errorf("could not remove diagram from cache: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue