Skip to content

Commit

Permalink
refactor: use ULID as Request ID and re-use as workdir name
Browse files Browse the repository at this point in the history
Using the same ID allows associating the request with its (generated)
files more easily, although this is only useful with --keep-jobs=always
or --keep-jobs=on-failure.

To decrease the chance of ID collisions, we're switching from manually
generating 48 bits in base64 encoding to ULID [1], which boast a 48 bit
timestamp with ms precision and 80 bits of randomness.

[1]: https://github.com/oklog/ulid
  • Loading branch information
dmke committed Oct 30, 2024
1 parent 5a00042 commit 5612092
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 6 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ require (
github.com/gorilla/handlers v1.5.2
github.com/gorilla/mux v1.8.1
github.com/moby/term v0.5.0
github.com/oklog/ulid/v2 v2.1.0
github.com/opencontainers/image-spec v1.1.0
github.com/prometheus/client_golang v1.20.5
github.com/spf13/afero v1.11.0
Expand Down
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1476,6 +1476,8 @@ github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/oklog/ulid/v2 v2.1.0 h1:+9lhoxAP56we25tyYETBBY1YLA2SaoLvUFgrP2miPJU=
github.com/oklog/ulid/v2 v2.1.0/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
Expand All @@ -1490,6 +1492,7 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY=
github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=
Expand Down
8 changes: 4 additions & 4 deletions service/middleware/requestid.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ package middleware
import (
"context"
"crypto/rand"
"encoding/base64"
"fmt"
"net/http"

"github.com/oklog/ulid/v2"
"go.uber.org/zap"
)

Expand All @@ -17,11 +17,11 @@ type contextKey string
const ContextKey = contextKey("request-id")

func generateRequestId() string {
b := make([]byte, 6)
if _, err := rand.Read(b); err != nil {
id, err := ulid.New(ulid.Now(), rand.Reader)
if err != nil {
panic(fmt.Errorf("rand error: %w", err))
}
return base64.RawURLEncoding.EncodeToString(b)
return id.String()
}

func RequestID(next http.Handler) http.Handler {
Expand Down
3 changes: 3 additions & 0 deletions service/renderer.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ func (svc *service) render(log *zap.Logger, res http.ResponseWriter, req *http.R
defer svc.release()

doc := tex.NewDocument(log, engine, image)
if id, ok := middleware.GetRequestID(req); ok {
doc.SetWorkingDirName(id)
}
defer func() {
if svc.shouldKeepJobs(err) {
return
Expand Down
26 changes: 24 additions & 2 deletions tex/document.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io"
"os"
"path"
"path/filepath"
"strings"
"sync"

Expand Down Expand Up @@ -101,6 +102,14 @@ type Document interface {
// named directory.
WorkingDirectory() (string, error)

// SetWorkingDirName disables the randomness of WorkingDirectory() by
// providing a static name. Extra care should be taken to ensure
// concurrent renderings don't accidentally happen in the same directory.
//
// Calling this method after WorkingDirectory(), AddFile(), or
// NewWriter() doesn't have an effect.
SetWorkingDirName(name string)

// AddFile saves the given content as a file in the document's
// working directory, with the given name.
//
Expand Down Expand Up @@ -179,8 +188,9 @@ type document struct {
image string
engine Engine

mkWorkDir *sync.Once
mkWorkDirErr error
mkWorkDirName string
mkWorkDir *sync.Once
mkWorkDirErr error
}

var _ Document = (*document)(nil)
Expand All @@ -205,13 +215,25 @@ func (doc *document) WorkingDirectory() (string, error) {
}

func (doc *document) createWorkDir() {
if doc.mkWorkDirName != "" {
doc.workdir = filepath.Join(baseJobDir, doc.mkWorkDirName)
return
}

if wd, err := afero.TempDir(doc.fs, baseJobDir, "texd-"); err != nil {
doc.mkWorkDirErr = UnknownError("creating working directory failed", err, nil)
} else {
doc.workdir = wd
}
}

func (doc *document) SetWorkingDirName(name string) {
if doc.workdir != "" {
return // createWorkDir was already called
}
doc.mkWorkDirName = name
}

func (doc *document) AddFile(name, contents string) error {
wc, err := doc.NewWriter(name)
if err != nil {
Expand Down

0 comments on commit 5612092

Please sign in to comment.