git-lfs/transfer/transfer.go

126 lines
4.1 KiB
Go
Raw Normal View History

// Package transfer collects together adapters for uploading and downloading LFS content
// NOTE: Subject to change, do not rely on this package from outside git-lfs source
package transfer
import "github.com/github/git-lfs/progress"
type Direction int
const (
Upload = Direction(iota)
Download = Direction(iota)
)
var (
downloadAdapters = make(map[string]TransferAdapter)
uploadAdapters = make(map[string]TransferAdapter)
)
// TransferAdapter is implemented by types which can upload and/or download LFS
// file content to a remote store. Each TransferAdapter accepts one or more requests
// which it may schedule and parallelise in whatever way it chooses, clients of
// this interface will receive notifications of progress and completion asynchronously.
// TransferAdapters support transfers in one direction; you should use implementations
// of the sub-interface UploadAdapter and DownloadAdapter for groups of items in
// a direction.
type TransferAdapter interface {
// Name returns the identifier of this adapter, must be unique within a Direction
// (separate sets for upload and download so may be an entry in both)
Name() string
// Direction returns whether this instance is an upload or download instance
// TransferAdapter instances can only be one or the other, although the same
// type may be instantiated once for each direction
Direction() Direction
// Begin a new batch of uploads or downloads. Call this first, followed by
// one or more Add calls. The passed in callback will receive updates on
// progress, and the completion channel will receive completion notifications
Begin(cb progress.CopyCallback, completion chan TransferResult) error
// Add queues a download/upload, which will complete asynchronously and
// notify the callbacks given to Begin()
Add(t Transfer)
// Indicate that all transfers have been scheduled and resources can be released
// once the queued items have completed.
// This call blocks until all items have been processed
End() error
// ClearTempStorage clears any temporary files, such as unfinished downloads that
// would otherwise be resumed
ClearTempStorage() error
}
// General struct for both uploads and downloads
type Transfer struct {
// Name of the file that triggered this transfer
Name string
// oid identifier
Oid string
// size of file to be transferred
Size int64
// link which api provided as source/dest for this transfer
Link string
// Path for uploads is the source of data to send, for downloads is the
// location to place the final result
Path string
}
// Result of a transfer returned through CompletionChannel()
type TransferResult struct {
*Transfer
// This will be non-nil if there was an error transferring this item
Error error
}
// GetAdapters returns a list of registered adapters for the given direction
func GetAdapters(dir Direction) []TransferAdapter {
switch dir {
case Upload:
return GetUploadAdapters()
case Download:
return GetDownloadAdapters()
}
return nil
}
// GetDownloadAdapters returns a list of registered adapters able to perform downloads
func GetDownloadAdapters() []TransferAdapter {
ret := make([]TransferAdapter, 0, len(downloadAdapters))
for _, a := range downloadAdapters {
ret = append(ret, a)
}
return ret
}
// GetUploadAdapters returns a list of registered adapters able to perform uploads
func GetUploadAdapters() []TransferAdapter {
ret := make([]TransferAdapter, 0, len(uploadAdapters))
for _, a := range uploadAdapters {
ret = append(ret, a)
}
return ret
}
// RegisterAdapter registers an upload or download adapter. If an adapter is
// already registered for that direction with the same name, it is overridden
func RegisterAdapter(adapter TransferAdapter) {
switch adapter.Direction() {
case Upload:
uploadAdapters[adapter.Name()] = adapter
case Download:
downloadAdapters[adapter.Name()] = adapter
}
}
// Get a specific adapter by name and direction
func GetAdapter(name string, dir Direction) (TransferAdapter, bool) {
switch dir {
case Upload:
if u, ok := uploadAdapters[name]; ok {
return u, true
}
case Download:
if d, ok := downloadAdapters[name]; ok {
return d, true
}
}
return nil, false
}