Documentation ¶
Index ¶
- Constants
- Variables
- func CreateHandler(typ string, loader Loader, config jsonconfig.Obj) (http.Handler, error)
- func EnumerateAll(src BlobEnumerator, fn func(blobref.SizedBlobRef) error) error
- func MergedEnumerate(dest chan<- blobref.SizedBlobRef, sources []Storage, after string, limit int, ...) error
- func RegisterHandlerConstructor(typ string, ctor HandlerConstructor)
- func RegisterStorageConstructor(typ string, ctor StorageConstructor)
- func StatBlob(bs BlobStatter, br *blobref.BlobRef) (sb blobref.SizedBlobRef, err error)
- func Unwrap(sto interface{}) interface{}
- type BlobEnumerator
- type BlobHub
- type BlobReceiveConfiger
- type BlobReceiver
- type BlobStatter
- type Cache
- type Config
- type Configer
- type ContextWrapper
- type FindHandlerByTyper
- type GenerationNotSupportedError
- type Generationer
- type HandlerConstructor
- type Loader
- type MaxEnumerateConfig
- type NoImplStorage
- func (nis *NoImplStorage) EnumerateBlobs(dest chan<- blobref.SizedBlobRef, after string, limit int, wait time.Duration) error
- func (nis *NoImplStorage) Fetch(*blobref.BlobRef) (file blobref.ReadSeekCloser, size int64, err error)
- func (nis *NoImplStorage) FetchStreaming(*blobref.BlobRef) (file io.ReadCloser, size int64, err error)
- func (nis *NoImplStorage) GetBlobHub() BlobHub
- func (nis *NoImplStorage) ReceiveBlob(blob *blobref.BlobRef, source io.Reader) (sb blobref.SizedBlobRef, err error)
- func (nis *NoImplStorage) RemoveBlobs(blobs []*blobref.BlobRef) error
- func (nis *NoImplStorage) StatBlobs(dest chan<- blobref.SizedBlobRef, blobs []*blobref.BlobRef, wait time.Duration) error
- type QueueCreator
- type SimpleBlobHub
- func (h *SimpleBlobHub) NotifyBlobReceived(blob *blobref.BlobRef)
- func (h *SimpleBlobHub) RegisterBlobListener(blob *blobref.BlobRef, ch chan *blobref.BlobRef)
- func (h *SimpleBlobHub) RegisterListener(ch chan *blobref.BlobRef)
- func (h *SimpleBlobHub) UnregisterBlobListener(blob *blobref.BlobRef, ch chan *blobref.BlobRef)
- func (h *SimpleBlobHub) UnregisterListener(ch chan *blobref.BlobRef)
- type SimpleBlobHubPartitionMap
- type StatReceiver
- type Storage
- type StorageConfiger
- type StorageConstructor
- type StorageQueueCreator
Constants ¶
const MaxBlobSize = 16 << 20
MaxBlobSize is the size of a single blob in Camlistore.
TODO: formalize this in the specs. This value of 16 MB is less than App Engine's 32 MB request limit, much more than Venti's limit, and much more than the ~64 KB & 256 KB chunks that the FileWriter make
Variables ¶
var ErrCorruptBlob = errors.New("corrupt blob; digest doesn't match")
var ErrHandlerTypeNotFound = errors.New("requested handler type not loaded")
Functions ¶
func CreateHandler ¶
func EnumerateAll ¶
func EnumerateAll(src BlobEnumerator, fn func(blobref.SizedBlobRef) error) error
EnumerateAll runs fn for each blob in src. If fn returns an error, iteration stops and fn isn't called again. EnumerateAll will not return concurrently with fn.
func MergedEnumerate ¶
func MergedEnumerate(dest chan<- blobref.SizedBlobRef, sources []Storage, after string, limit int, wait time.Duration) error
TODO: it'd be nice to make sources be []BlobEnumerator, but that makes callers more complex since assignable interfaces' slice forms aren't assignable.
func RegisterHandlerConstructor ¶
func RegisterHandlerConstructor(typ string, ctor HandlerConstructor)
func RegisterStorageConstructor ¶
func RegisterStorageConstructor(typ string, ctor StorageConstructor)
func StatBlob ¶
func StatBlob(bs BlobStatter, br *blobref.BlobRef) (sb blobref.SizedBlobRef, err error)
Types ¶
type BlobEnumerator ¶
type BlobEnumerator interface { // EnumerateBobs sends at most limit SizedBlobRef into dest, // sorted, as long as they are lexigraphically greater than // after (if provided). // limit will be supplied and sanity checked by caller. // wait is the max time to wait for any blobs to exist, // or 0 for no delay. // EnumerateBlobs must close the channel. (even if limit // was hit and more blobs remain) // // after and waitSeconds can't be used together. One must be // its zero value. EnumerateBlobs(dest chan<- blobref.SizedBlobRef, after string, limit int, wait time.Duration) error }
type BlobHub ¶
type BlobHub interface { // For new blobs to notify NotifyBlobReceived(blob *blobref.BlobRef) RegisterListener(ch chan *blobref.BlobRef) UnregisterListener(ch chan *blobref.BlobRef) RegisterBlobListener(blob *blobref.BlobRef, ch chan *blobref.BlobRef) UnregisterBlobListener(blob *blobref.BlobRef, ch chan *blobref.BlobRef) }
type BlobReceiveConfiger ¶
type BlobReceiveConfiger interface { BlobReceiver Configer }
type BlobReceiver ¶
type BlobStatter ¶
type BlobStatter interface { // Stat checks for the existence of blobs, writing their sizes // (if found back to the dest channel), and returning an error // or nil. Stat() should NOT close the channel. // wait is the max time to wait for the blobs to exist, // or 0 for no delay. StatBlobs(dest chan<- blobref.SizedBlobRef, blobs []*blobref.BlobRef, wait time.Duration) error }
type Cache ¶
type Cache interface { blobref.SeekFetcher BlobReceiver BlobStatter }
Cache is the minimal interface expected of a blob cache.
type Config ¶
type Config struct {
Writable, Readable bool
IsQueue bool // supports deletes
CanLongPoll bool
// the "http://host:port" and optional path (but without trailing slash) to have "/camli/*" appended
URLBase string
HandlerFinder FindHandlerByTyper
}
type ContextWrapper ¶
ContextWrapper is an optional interface for App Engine.
While Camlistore's internals are separated out into a part which maps HTTP requests to the interfaces in this file (pkg/blobserver/handlers) and parts which map these interfaces to implementations (localdisk, s3, etc), the App Engine implementation requires access to the original HTTP request. (because a security token is stored on the incoming HTTP request in a magic header). All the handlers will do an interface check on this type and use the resulting Storage instead.
type FindHandlerByTyper ¶
type FindHandlerByTyper interface { // FindHandlerByType finds a handler by its handlerType and // returns its prefix and handler if it's loaded. If it's not // loaded, the error will be ErrHandlerTypeNotFound. // // This is used by handlers to find siblings (such as the "ui" type handler) // which might have more knowledge about the configuration for discovery, etc. // // Note that if this is called during handler construction // time, only the prefix may be returned with a nil handler // and nil err. Unlike GetHandler and GetStorage, this does // not cause the prefix to load immediately. At runtime (after // construction of all handlers), then prefix and handler will // both be non-nil when err is nil. FindHandlerByType(handlerType string) (prefix string, handler interface{}, err error) }
type GenerationNotSupportedError ¶
type GenerationNotSupportedError string
A GenerationNotSupportedError explains why a Storage value implemented the Generationer interface but failed due to a wrapped Storage value not implementing the interface.
func (GenerationNotSupportedError) Error ¶
func (s GenerationNotSupportedError) Error() string
type Generationer ¶
type Generationer interface { // Generation returns a Storage's initialization time and // and unique random string (or UUID). Implementations // should call ResetStorageGeneration on demand if no // information is known. // The error will be of type GenerationNotSupportedError if an underlying // storage target doesn't support the Generationer interface. StorageGeneration() (initTime time.Time, random string, err error) // ResetGeneration deletes the information returned by Generation // and re-generates it. ResetStorageGeneration() error }
The optional Generationer interface is an optimization and paranoia facility for clients which can be implemented by Storage implementations.
If the client sees the same random string in multiple upload sessions, it assumes that the blobserver still has all the same blobs, and also it's the same server. This mechanism is not fundamental to Camlistore's operation: the client could also check each blob before uploading, or enumerate all blobs from the server too. This is purely an optimization so clients can mix this value into their "is this file uploaded?" local cache keys.
type HandlerConstructor ¶
type Loader ¶
type Loader interface { FindHandlerByTyper // MyPrefix returns the prefix of the handler currently being constructed. MyPrefix() string // GetHandlerType returns the handler's configured type, but does // not force it to start being loaded yet. GetHandlerType(prefix string) string // returns "" if unknown // GetHandler returns either a Storage or an http.Handler. // It forces the handler to be loaded and returns an error if // a cycle is created. GetHandler(prefix string) (interface{}, error) // GetStorage is like GetHandler but requires that the Handler be // a storage Handler. GetStorage(prefix string) (Storage, error) // If we're loading configuration in response to a web request // (as we do with App Engine), then this returns a request and // true. GetRequestContext() (ctx *http.Request, ok bool) }
type MaxEnumerateConfig ¶
type MaxEnumerateConfig interface { // Returns the max that this storage interface is capable // of enumerating at once. MaxEnumerate() int }
type NoImplStorage ¶
type NoImplStorage struct { }
func (*NoImplStorage) EnumerateBlobs ¶
func (nis *NoImplStorage) EnumerateBlobs(dest chan<- blobref.SizedBlobRef, after string, limit int, wait time.Duration) error
func (*NoImplStorage) Fetch ¶
func (nis *NoImplStorage) Fetch(*blobref.BlobRef) (file blobref.ReadSeekCloser, size int64, err error)
func (*NoImplStorage) FetchStreaming ¶
func (nis *NoImplStorage) FetchStreaming(*blobref.BlobRef) (file io.ReadCloser, size int64, err error)
func (*NoImplStorage) GetBlobHub ¶
func (nis *NoImplStorage) GetBlobHub() BlobHub
func (*NoImplStorage) ReceiveBlob ¶
func (nis *NoImplStorage) ReceiveBlob(blob *blobref.BlobRef, source io.Reader) (sb blobref.SizedBlobRef, err error)
func (*NoImplStorage) RemoveBlobs ¶
func (nis *NoImplStorage) RemoveBlobs(blobs []*blobref.BlobRef) error
func (*NoImplStorage) StatBlobs ¶
func (nis *NoImplStorage) StatBlobs(dest chan<- blobref.SizedBlobRef, blobs []*blobref.BlobRef, wait time.Duration) error
type QueueCreator ¶
QueueCreator is implemented by Storage interfaces which support creating queues in which all new uploads go to both the root storage as well as the named queue, which is then returned. This is used by replication.
type SimpleBlobHub ¶
type SimpleBlobHub struct {
// contains filtered or unexported fields
}
func (*SimpleBlobHub) NotifyBlobReceived ¶
func (h *SimpleBlobHub) NotifyBlobReceived(blob *blobref.BlobRef)
func (*SimpleBlobHub) RegisterBlobListener ¶
func (h *SimpleBlobHub) RegisterBlobListener(blob *blobref.BlobRef, ch chan *blobref.BlobRef)
func (*SimpleBlobHub) RegisterListener ¶
func (h *SimpleBlobHub) RegisterListener(ch chan *blobref.BlobRef)
func (*SimpleBlobHub) UnregisterBlobListener ¶
func (h *SimpleBlobHub) UnregisterBlobListener(blob *blobref.BlobRef, ch chan *blobref.BlobRef)
func (*SimpleBlobHub) UnregisterListener ¶
func (h *SimpleBlobHub) UnregisterListener(ch chan *blobref.BlobRef)
type SimpleBlobHubPartitionMap ¶
type SimpleBlobHubPartitionMap struct {
// contains filtered or unexported fields
}
func (*SimpleBlobHubPartitionMap) GetBlobHub ¶
func (spm *SimpleBlobHubPartitionMap) GetBlobHub() BlobHub
type StatReceiver ¶
type StatReceiver interface { BlobReceiver BlobStatter }
type Storage ¶
type Storage interface { blobref.StreamingFetcher BlobReceiver BlobStatter BlobEnumerator // Remove 0 or more blobs. Removal of non-existent items // isn't an error. Returns failure if any items existed but // failed to be deleted. RemoveBlobs(blobs []*blobref.BlobRef) error // Returns the blob notification bus GetBlobHub() BlobHub }
func CreateStorage ¶
type StorageConfiger ¶
type StorageConstructor ¶
type StorageConstructor func(Loader, jsonconfig.Obj) (Storage, error)
type StorageQueueCreator ¶
type StorageQueueCreator interface { Storage QueueCreator }