blob: 5704edd8b4031f3040ed1ce2a86276e54ea1f61f [file] [log] [blame]
// Copyright 2015 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package storage
import (
"context"
"errors"
"go.chromium.org/luci/logdog/common/types"
)
var (
// ErrExists returned if an attempt is made to overwrite an existing record.
ErrExists = errors.New("storage: record exists")
// ErrDoesNotExist returned if an attempt is made to read a record that
// doesn't exist.
ErrDoesNotExist = errors.New("storage: record does not exist")
// ErrBadData is an error returned when the stored data is invalid.
ErrBadData = errors.New("storage: bad data")
// ErrReadOnly can be returned by Storage methods to indicate that the Storage
// is read-only.
ErrReadOnly = errors.New("storage: read only")
)
// PutRequest describes adding a single storage record to BigTable.
type PutRequest struct {
// Project is the project name of the stream.
Project string
// Path is the stream path to retrieve.
Path types.StreamPath
// Index is the entry's stream index.
Index types.MessageIndex
// Values are contiguous sequential records to add to the storage. The first
// index in values corresponds to Index.
Values [][]byte
}
// GetRequest is a request to retrieve a series of LogEntry records.
type GetRequest struct {
// Project is the project name of the stream.
Project string
// Path is the stream path to retrieve.
Path types.StreamPath
// Index is the entry's stream index.
Index types.MessageIndex
// Limit is the maximum number of records to return before stopping iteration.
// If <= 0, no maximum limit will be applied.
//
// The Storage instance may return fewer records than the supplied Limit as an
// implementation detail.
Limit int
// KeysOnly, if true, allows (but doesn't require) the Storage instance to
// omit entry data in its get callback. For scanning operations, this can be
// much cheaper/faster than full data queries.
KeysOnly bool
}
// GetCallback is invoked for each record in the Get request. If it returns
// false, iteration should stop.
//
// The MessageIndex may be -1 if the message index isn't known. In this case,
// the caller will have to unmarshal the log entry data to determine its index.
type GetCallback func(*Entry) bool
// ExpungeRequest is a request to expunge the data associated with this stream.
type ExpungeRequest struct {
// Project is the project name of the stream.
Project string
// Path is the stream path to remove from storage.
Path types.StreamPath
}
// Storage is an abstract LogDog storage implementation. Interfaces implementing
// this may be used to store and retrieve log records by the collection service
// layer.
//
// All of these methods must be synchronous and goroutine-safe.
//
// All methods may return errors.Transient errors if they encounter an error
// that may be transient.
type Storage interface {
// Close shuts down this instance, releasing any allocated resources.
Close()
// Writes log record data to storage.
//
// If the data already exists, ErrExists will be returned.
Put(context.Context, PutRequest) error
// Get invokes a callback over a range of sequential LogEntry records.
//
// These log entries will be returned in order (e.g., seq(Rn) < seq(Rn+1)),
// but, depending on ingest, may not be contiguous.
//
// The underlying Storage implementation may return fewer records than
// requested based on availability or implementation details; consequently,
// receiving fewer than requested records does not necessarily mean that more
// records are not available.
//
// Returns nil if retrieval executed successfully, ErrDoesNotExist if
// the requested stream does not exist, and an error if an error occurred
// during retrieval.
Get(context.Context, GetRequest, GetCallback) error
// Expunge removes all entries related to the given project/path.
Expunge(context.Context, ExpungeRequest) error
// Tail retrieves the latest log in the stream. If the stream has no logs, it
// will fail with ErrDoesNotExist.
//
// The MessageIndex may be -1 if the message index isn't known. In this case,
// the caller will have to unmarshal the log entry data to determine its
// index.
Tail(ctx context.Context, projectName string, stream types.StreamPath) (*Entry, error)
}