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 }