go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/logdog/common/storage/storage.go (about) 1 // Copyright 2015 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package storage 16 17 import ( 18 "context" 19 "errors" 20 21 "go.chromium.org/luci/logdog/common/types" 22 ) 23 24 var ( 25 // ErrExists returned if an attempt is made to overwrite an existing record. 26 ErrExists = errors.New("storage: record exists") 27 28 // ErrDoesNotExist returned if an attempt is made to read a record that 29 // doesn't exist. 30 ErrDoesNotExist = errors.New("storage: record does not exist") 31 32 // ErrBadData is an error returned when the stored data is invalid. 33 ErrBadData = errors.New("storage: bad data") 34 35 // ErrReadOnly can be returned by Storage methods to indicate that the Storage 36 // is read-only. 37 ErrReadOnly = errors.New("storage: read only") 38 ) 39 40 // PutRequest describes adding a single storage record to BigTable. 41 type PutRequest struct { 42 // Project is the project name of the stream. 43 Project string 44 // Path is the stream path to retrieve. 45 Path types.StreamPath 46 // Index is the entry's stream index. 47 Index types.MessageIndex 48 49 // Values are contiguous sequential records to add to the storage. The first 50 // index in values corresponds to Index. 51 Values [][]byte 52 } 53 54 // GetRequest is a request to retrieve a series of LogEntry records. 55 type GetRequest struct { 56 // Project is the project name of the stream. 57 Project string 58 // Path is the stream path to retrieve. 59 Path types.StreamPath 60 // Index is the entry's stream index. 61 Index types.MessageIndex 62 63 // Limit is the maximum number of records to return before stopping iteration. 64 // If <= 0, no maximum limit will be applied. 65 // 66 // The Storage instance may return fewer records than the supplied Limit as an 67 // implementation detail. 68 Limit int 69 // KeysOnly, if true, allows (but doesn't require) the Storage instance to 70 // omit entry data in its get callback. For scanning operations, this can be 71 // much cheaper/faster than full data queries. 72 KeysOnly bool 73 } 74 75 // GetCallback is invoked for each record in the Get request. If it returns 76 // false, iteration should stop. 77 // 78 // The MessageIndex may be -1 if the message index isn't known. In this case, 79 // the caller will have to unmarshal the log entry data to determine its index. 80 type GetCallback func(*Entry) bool 81 82 // ExpungeRequest is a request to expunge the data associated with this stream. 83 type ExpungeRequest struct { 84 // Project is the project name of the stream. 85 Project string 86 // Path is the stream path to remove from storage. 87 Path types.StreamPath 88 } 89 90 // Storage is an abstract LogDog storage implementation. Interfaces implementing 91 // this may be used to store and retrieve log records by the collection service 92 // layer. 93 // 94 // All of these methods must be synchronous and goroutine-safe. 95 // 96 // All methods may return errors.Transient errors if they encounter an error 97 // that may be transient. 98 type Storage interface { 99 // Close shuts down this instance, releasing any allocated resources. 100 Close() 101 102 // Writes log record data to storage. 103 // 104 // If the data already exists, ErrExists will be returned. 105 Put(context.Context, PutRequest) error 106 107 // Get invokes a callback over a range of sequential LogEntry records. 108 // 109 // These log entries will be returned in order (e.g., seq(Rn) < seq(Rn+1)), 110 // but, depending on ingest, may not be contiguous. 111 // 112 // The underlying Storage implementation may return fewer records than 113 // requested based on availability or implementation details; consequently, 114 // receiving fewer than requested records does not necessarily mean that more 115 // records are not available. 116 // 117 // Returns nil if retrieval executed successfully, ErrDoesNotExist if 118 // the requested stream does not exist, and an error if an error occurred 119 // during retrieval. 120 Get(context.Context, GetRequest, GetCallback) error 121 122 // Expunge removes all entries related to the given project/path. 123 Expunge(context.Context, ExpungeRequest) error 124 125 // Tail retrieves the latest log in the stream. If the stream has no logs, it 126 // will fail with ErrDoesNotExist. 127 // 128 // The MessageIndex may be -1 if the message index isn't known. In this case, 129 // the caller will have to unmarshal the log entry data to determine its 130 // index. 131 Tail(ctx context.Context, projectName string, stream types.StreamPath) (*Entry, error) 132 }