Add remaining code for diagram cleanup

This commit is contained in:
Tom Wright 2020-08-09 10:59:05 +01:00
parent 0461b59150
commit f1f2012a95
5 changed files with 144 additions and 2 deletions

26
.github/workflows/build.yaml vendored Normal file
View File

@ -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 }}

24
.github/workflows/test.yaml vendored Normal file
View File

@ -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 ./...

View File

@ -10,6 +10,10 @@ type DiagramCache interface {
Has(diagram *Diagram) (bool, error)
// Get returns a cached version of the given diagram description.
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.
@ -57,3 +61,27 @@ func (c *inMemoryDiagramCache) Get(diagram *Diagram) (*Diagram, error) {
}
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
}

View File

@ -5,22 +5,45 @@ import (
"encoding/base64"
"encoding/hex"
"strings"
"sync"
"time"
)
// NewDiagram returns a new diagram.
func NewDiagram(description []byte) *Diagram {
return &Diagram{
description: []byte(strings.TrimSpace(string(description))),
lastTouched: time.Now(),
mu: &sync.RWMutex{},
}
}
// Diagram represents a single diagram.
type Diagram struct {
// iD is the ID of the Diagram
// id is the ID of the Diagram
id string
// description is the description of the diagram.
description []byte
// Output is the filepath to the output file.
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.

View File

@ -51,8 +51,17 @@ func (c cachingGenerator) Generate(diagram *Diagram) error {
return fmt.Errorf("cache.Get failed: %w", err)
}
*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
}
diagram.Touch()
if err := c.generate(diagram); err != nil {
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.
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
}