Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhanced transfers: part 1 #1265

Merged
merged 37 commits into from Jun 7, 2016
Merged

Enhanced transfers: part 1 #1265

merged 37 commits into from Jun 7, 2016

Conversation

sinbad
Copy link
Contributor

@sinbad sinbad commented May 31, 2016

Part 1 of supporting more flexible transfer mechanisms for upload & download. This PR changes no visible behaviour or APIs but prepares the ground for features like resumable transfers and binary chunking/diffing.

The major changes are:

  1. the code for actually performing the uploads and downloads is now isolated in the transfer package
  2. paths for uploading / downloading are abstracted via a TransferAdapter, and the existing path of non-resumable HTTP GET/PUT is implemented as basicTransferAdapter
  3. TransferAdapter implementations are unidirectional, to allow for paths that can only do one or the other (e.g. tus.io is only upload, HTTP range headers are only download)
  4. a registration system for adding new named transfer adapters is in place but currently unused, will be in the next stage
  5. rationalisation of much of the API code so there is a clearer line between the API which requests URLs to upload/download, and the code which actually performs the upload/download.
  6. TransferQueue is still used since it orchestrates the end-to-end process, which includes calling the API. However it no longer has any transfer workers, it delegates that to TransferAdapter.
  7. Legacy code which will be removed when we drop the non-batch API route is clearly marked // TODO LEGACY API. Use of this code has been minimised so it's no longer generally mixed in even when you have batch support.
  8. Fixes Serious usability issues prompting for credentials with an separate LFS server #1121 - this was caused by only the API part of the download/upload exchange waiting for a password prompt in serial, the actual transfers all kicked off in parallel so if the storage server had different credentials and had to prompt, all goroutines would prompt. The transfer system now handles this itself.
  9. The same transfer code path is used for all cases, whether you're using e.g. git lfs fetch or git lfs smudge. Previously there were multiple paths.
  10. Removed the DownloadCheckable and simplified things so it just uses the dryRun flag instead when probing the API for possible downloads without actually downloading. No other code used this anyway.
  11. Transferable still exists but is now just a statement of intent in the lfs package for the entire process of queueing through the API and eventually being transferred if dryRun=false. It still needs to be there as an abstraction since the data comes from different places, but beyond data wrapping has no real functionality anymore barring a legacy hook which will get removed when we move to batch only. The simpler Transfer struct in the transfer package is used to schedule the actual transfers (doesn't share Transferable both to avoid import cycles and because the intent is different)

As mentioned this is only an internal change right now (albeit a fairly large one) and behaviour is unaffected. The next step is to use the adapter registration system to provide additional transfer routes, negotiated between client & server through optional new fields in the API.

sinbad added 30 commits May 18, 2016 16:54
Also remove old api functions and users, mark legacy more clearly
Pare down old unit tests which used the legacy api
# Conflicts:
#	lfs/pointer_smudge.go
#	lfs/transfer_queue.go
#	lfs/util_test.go
@sinbad sinbad added the review label May 31, 2016
@sinbad
Copy link
Contributor Author

sinbad commented May 31, 2016

/cc @technoweenie @ttaylorr

// BatchOrLegacy calls the Batch API and falls back on the Legacy API
// This is for simplicity, legacy route is not most optimal (serial)
// TODO LEGACY API: remove when legacy API removed
func BatchOrLegacy(objects []*ObjectResource, operation string) ([]*ObjectResource, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about a note in the documentation that says announces we set "lfs.batch" to false locally if the batch operation is unsupported?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually want us to stop doing this in 1.3 & remove the legacy API. The persistent lfs.batch=false setting is a regular source of support calls when something has gone wrong either on the server, or some step in between and then persistently the LFS client refuses to use batch any more. If we keep lfs.batch in 1.3 then I'll push for adding a big warning banner in every fetch/push/pull that tells people lfs.batch=false and suggests removing it. What we do with batch/legacy is outside the scope of this PR though.

@sinbad sinbad merged commit 1789729 into master Jun 7, 2016
@sinbad sinbad deleted the experimental/transfer-features branch June 7, 2016 08:35
chrisd8088 added a commit to chrisd8088/git-lfs that referenced this pull request Jul 21, 2021
The ClearTempStorage() method of the transfer Adapter interface,
while implemented for most adapters, is never actually called,
and moreover is dangerous in some its current implementations
if it were ever to be called.

Specifically in the basic upload and download adapters and the
SSH adapter, the ClearTempStorage() method relies on an internal
tempDir() method to return the path to the temporary directory
to be cleared, which ClearTempStorage() then removes entirely.

The tempDir() methods, however, can return os.TempDir() if they
are unable to create a local temporary directory within the
Git LFS storage directory, and also do not cache the path to
the directory they first returned.  So were ClearTempStorage()
ever to be called in one of these adapters, its invocation of
tempDir() might just return the system temporary directory
(e.g., /tmp on Unix), which it would then attempt to remove.

The ClearTempStorage() method was introduced in commits
f124f05 and
940a91a of PR git-lfs#1265, but
has never been called by any user of the transfer
adapter interface.

We therefore just remove this method and its implemetations
from all the current tranfer adapters.
pcal43 pushed a commit to pcal43/git-lfs-hack that referenced this pull request Jul 22, 2021
The ClearTempStorage() method of the transfer Adapter interface,
while implemented for most adapters, is never actually called,
and moreover is dangerous in some its current implementations
if it were ever to be called.

Specifically in the basic upload and download adapters and the
SSH adapter, the ClearTempStorage() method relies on an internal
tempDir() method to return the path to the temporary directory
to be cleared, which ClearTempStorage() then removes entirely.

The tempDir() methods, however, can return os.TempDir() if they
are unable to create a local temporary directory within the
Git LFS storage directory, and also do not cache the path to
the directory they first returned.  So were ClearTempStorage()
ever to be called in one of these adapters, its invocation of
tempDir() might just return the system temporary directory
(e.g., /tmp on Unix), which it would then attempt to remove.

The ClearTempStorage() method was introduced in commits
f124f05 and
940a91a of PR git-lfs#1265, but
has never been called by any user of the transfer
adapter interface.

We therefore just remove this method and its implemetations
from all the current tranfer adapters.
chrisd8088 added a commit to chrisd8088/git-lfs that referenced this pull request Jul 27, 2023
The three test functions in the tq/transfer_test.go source file are
all named with the prefix "test" rather than "Test", and as a result,
do not actually execute.  This oversight dates from the original
introduction of these tests in the "transfer" package in commit
10623f5 of PR git-lfs#1265.  (The package
was later renamed to the current "tq" package in commit
891db97 of PR git-lfs#1780.)

We therefore change the test function names to begin with "Test",
and resolve several test regressions which have accumulated since the
tests were first added.

First, the TestBasicAdapterExists() function calls the
GetDownloadAdapterNames() and GetUploadAdapterNames() methods of the
Manifest structure, and these now return the names of three transfer
adapter implementations rather than just the original "basic" one,
so we allow for all three names to appear in any order.  (The
"lfs-standalone-file" adapter was added in commit
bb05cf5 of PR git-lfs#3748, and the "ssh"
adapter was added in commit 594f8e3
of PR git-lfs#4446.)

Second, the TestAdapterRegAndOverride() function expects the
NewDownloadAdapter() and NewUploadAdapter() methods of the Manifest
structure to return nil if the provided name argument does not match
that of any registered transfer adapter.  However, this has not been
the behaviour of those methods since commit
c5c2a75 of PR git-lfs#1279, shortly after
the tests were first introduced in PR git-lfs#1265.  In that commit, the
NewAdapterOrDefault() method was added, and the NewDownloadAdapter()
and NewUploadAdapter() revised to call it, so they return the
default "basic" adapter if the requested name does not match a
registered adapter.  We therefore revise and expand the test to
account for this behaviour, and also make sure to directly test the
simpler NewAdapter() method, which retains the originally intended
behaviour and returns nil if it does not find a matching adapter
for the provided name argument.
chrisd8088 added a commit to chrisd8088/git-lfs that referenced this pull request Jul 27, 2023
The three test functions in the tq/transfer_test.go source file are
all named with the prefix "test" rather than "Test", and as a result,
do not actually execute.  This oversight dates from the original
introduction of these tests in the "transfer" package in commit
10623f5 of PR git-lfs#1265.  (The package
was later renamed to the current "tq" package in commit
891db97 of PR git-lfs#1780.)

We therefore change the test function names to begin with "Test",
and resolve several test regressions which have accumulated since the
tests were first added.

First, the TestBasicAdapterExists() function calls the
GetDownloadAdapterNames() and GetUploadAdapterNames() methods of the
Manifest structure, and these now return the names of three transfer
adapter implementations rather than just the original "basic" one,
so we allow for all three names to appear in any order.  (The
"lfs-standalone-file" adapter was added in commit
bb05cf5 of PR git-lfs#3748, and the "ssh"
adapter was added in commit 594f8e3
of PR git-lfs#4446.)

Second, the TestAdapterRegAndOverride() function expects the
NewDownloadAdapter() and NewUploadAdapter() methods of the Manifest
structure to return nil if the provided name argument does not match
that of any registered transfer adapter.  However, this has not been
the behaviour of those methods since commit
c5c2a75 of PR git-lfs#1279, shortly after
the tests were first introduced in PR git-lfs#1265.  In that commit, the
NewAdapterOrDefault() method was added, and the NewDownloadAdapter()
and NewUploadAdapter() revised to call it, so they return the
default "basic" adapter if the requested name does not match a
registered adapter.  We therefore revise and expand the test to
account for this behaviour, and also make sure to directly test the
simpler NewAdapter() method, which retains the originally intended
behaviour and returns nil if it does not find a matching adapter
for the provided name argument.

Third, the TestAdapterRegButBasicOnly() function, which passes without
changes, no longer fully performs the checks it was intended to make,
since the NewDownloadAdapter() and NewUploadAdapter() methods now always
return a non-nil value, so using a non-nil response from them to prove
that the "test" adapter is found is insufficient.  We therefore update
the test to confirm that the returned value from these functions is
a "test" adapter, as expected, and not just a "basic" one.

We also replace the use of the BasicAdapterName variable with the
"basic" string to align with the other tests.
chrisd8088 added a commit to chrisd8088/git-lfs that referenced this pull request Jul 27, 2023
The three test functions in the tq/transfer_test.go source file are
all named with the prefix "test" rather than "Test", and as a result,
do not actually execute.  This oversight dates from the original
introduction of these tests in the "transfer" package in commit
10623f5 of PR git-lfs#1265.  (The package
was later renamed to the current "tq" package in commit
891db97 of PR git-lfs#1780.)

We therefore change the test function names to begin with "Test",
and resolve several test regressions which have accumulated since the
tests were first added.

First, the TestBasicAdapterExists() function calls the
GetDownloadAdapterNames() and GetUploadAdapterNames() methods of the
Manifest structure, and these now return the names of three transfer
adapter implementations rather than just the original "basic" one,
so we allow for all three names to appear in any order.  (The
"lfs-standalone-file" adapter was added in commit
bb05cf5 of PR git-lfs#3748, and the "ssh"
adapter was added in commit 594f8e3
of PR git-lfs#4446.)

Second, the TestAdapterRegAndOverride() function expects the
NewDownloadAdapter() and NewUploadAdapter() methods of the Manifest
structure to return nil if the provided name argument does not match
that of any registered transfer adapter.  However, this has not been
the behaviour of those methods since commit
c5c2a75 of PR git-lfs#1279, shortly after
the tests were first introduced in PR git-lfs#1265.  In that commit, the
NewAdapterOrDefault() method was added, and the NewDownloadAdapter()
and NewUploadAdapter() methods revised to call it, so they return the
default "basic" adapter if the requested name does not match a
registered adapter.  We therefore revise and expand the test to
account for this behaviour, and also make sure to directly test the
underlying NewAdapter() method, which retains the originally intended
behaviour and returns nil if it does not find a matching adapter
for the provided name argument.

Third, although the TestAdapterRegButBasicOnly() function passes without
changes, it no longer fully performs the checks it was intended to make,
since the NewDownloadAdapter() and NewUploadAdapter() methods now always
return a non-nil value, so using a non-nil response from them to prove
that the "test" adapter was found is insufficient.  We therefore update
the test to confirm that the returned value from these functions is
a "test" adapter, as expected, and not just a "basic" one.

We also replace the use of the BasicAdapterName variable with the
"basic" string to align with the other tests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants