src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

cacheprog.go (4472B)


      1 // Copyright 2024 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 // Package cacheprog defines the protocol for a GOCACHEPROG program.
      6 //
      7 // This is a port of cmd/go/internal/cacheprog from the Go standard library,
      8 // adapted for use with staticcheck.
      9 package cacheprog
     10 
     11 import (
     12 	"io"
     13 	"time"
     14 )
     15 
     16 // Cmd is a command that can be issued to a child process.
     17 //
     18 // If the interface needs to grow, new commands or new versioned commands like
     19 // "get2" can be added in the future. The initial [Response] from the child
     20 // process indicates which commands it supports.
     21 type Cmd string
     22 
     23 const (
     24 	// CmdPut tells the cache program to store an object in the cache.
     25 	//
     26 	// [Request.ActionID] is the cache key of this object. The cache should
     27 	// store [Request.OutputID] and [Request.Body] under this key for a
     28 	// later "get" request. It must also store the Body in a file in the local
     29 	// file system and return the path to that file in [Response.DiskPath],
     30 	// which must exist at least until a "close" request.
     31 	CmdPut = Cmd("put")
     32 
     33 	// CmdGet tells the cache program to retrieve an object from the cache.
     34 	//
     35 	// [Request.ActionID] specifies the key of the object to get. If the
     36 	// cache does not contain this object, it should set [Response.Miss] to
     37 	// true. Otherwise, it should populate the fields of [Response],
     38 	// including setting [Response.OutputID] to the OutputID of the original
     39 	// "put" request and [Response.DiskPath] to the path of a local file
     40 	// containing the Body of the original "put" request. That file must
     41 	// continue to exist at least until a "close" request.
     42 	CmdGet = Cmd("get")
     43 
     44 	// CmdClose requests that the cache program exit gracefully.
     45 	//
     46 	// The cache program should reply to this request and then exit
     47 	// (thus closing its stdout).
     48 	CmdClose = Cmd("close")
     49 )
     50 
     51 // Request is the JSON-encoded message that's sent from staticcheck to
     52 // the GOCACHEPROG child process over stdin. Each JSON object is on
     53 // its own line. A Request of type "put" with BodySize > 0 will be followed by
     54 // a line containing a base64-encoded JSON string literal of the body.
     55 type Request struct {
     56 	// ID is a unique number per process across all requests.
     57 	// It must be echoed in the Response from the child.
     58 	ID int64
     59 
     60 	// Command is the type of request.
     61 	// Only commands that were declared as supported by the child will be sent.
     62 	Command Cmd
     63 
     64 	// ActionID is the cache key for "put" and "get" requests.
     65 	ActionID []byte `json:",omitempty"` // or nil if not used
     66 
     67 	// OutputID is stored with the body for "put" requests.
     68 	OutputID []byte `json:",omitempty"` // or nil if not used
     69 
     70 	// Body is the body for "put" requests. It's sent after the JSON object
     71 	// as a base64-encoded JSON string when BodySize is non-zero.
     72 	Body io.Reader `json:"-"`
     73 
     74 	// BodySize is the number of bytes of Body. If zero, the body isn't written.
     75 	BodySize int64 `json:",omitempty"`
     76 }
     77 
     78 // Response is the JSON response from the child process to staticcheck.
     79 //
     80 // With the exception of the first protocol message that the child writes to its
     81 // stdout with ID==0 and KnownCommands populated, these are only sent in
     82 // response to a Request from staticcheck.
     83 //
     84 // Responses can be sent in any order. The ID must match the request they're
     85 // replying to.
     86 type Response struct {
     87 	ID  int64  // that corresponds to Request; they can be answered out of order
     88 	Err string `json:",omitempty"` // if non-empty, the error
     89 
     90 	// KnownCommands is included in the first message that cache helper program
     91 	// writes to stdout on startup (with ID==0). It includes the
     92 	// Request.Command types that are supported by the program.
     93 	//
     94 	// This lets the protocol be extended gracefully over time (adding
     95 	// "get2", etc), or fail gracefully when needed. It also lets us
     96 	// verify the program wants to be a cache helper.
     97 	KnownCommands []Cmd `json:",omitempty"`
     98 
     99 	// For "get" requests.
    100 
    101 	Miss     bool       `json:",omitempty"` // cache miss
    102 	OutputID []byte     `json:",omitempty"` // the OutputID stored with the body
    103 	Size     int64      `json:",omitempty"` // body size in bytes
    104 	Time     *time.Time `json:",omitempty"` // when the object was put in the cache (optional; used for cache expiration)
    105 
    106 	// For "get" and "put" requests.
    107 
    108 	// DiskPath is the absolute path on disk of the body corresponding to a
    109 	// "get" (on cache hit) or "put" request's ActionID.
    110 	DiskPath string `json:",omitempty"`
    111 }