Merge branch 'f30'
This commit is contained in:
commit
8b02cd9c47
1
.gitignore
vendored
1
.gitignore
vendored
@ -10,3 +10,4 @@
|
|||||||
/git-lfs-2.7.0.tar.gz
|
/git-lfs-2.7.0.tar.gz
|
||||||
/git-lfs-2.7.1.tar.gz
|
/git-lfs-2.7.1.tar.gz
|
||||||
/git-lfs-2.7.2.tar.gz
|
/git-lfs-2.7.2.tar.gz
|
||||||
|
/git-lfs-v2.8.0.tar.gz
|
||||||
|
124
3800.patch
Normal file
124
3800.patch
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
From d1ee735a4aacb80d9c3c4c34fc4317c6eef6718a Mon Sep 17 00:00:00 2001
|
||||||
|
From: "brian m. carlson" <bk2204@github.com>
|
||||||
|
Date: Wed, 28 Aug 2019 21:02:26 +0000
|
||||||
|
Subject: [PATCH] Avoid deadlock when transfer queue fails
|
||||||
|
|
||||||
|
In 1412d6e4 ("Don't fail if we lack objects the server has",
|
||||||
|
2019-04-30), we changed the code to abort later if a missing object
|
||||||
|
occurs. In doing so, we had to consider the case where the transfer
|
||||||
|
queue aborts early for some reason and ensure that the sync.WaitGroup
|
||||||
|
does not unnecessarily block due to outstanding objects never getting
|
||||||
|
processed.
|
||||||
|
|
||||||
|
However, the approach we used, which was to explicitly add the number of
|
||||||
|
items we skipped processing, was error prone and didn't cover all cases.
|
||||||
|
Notably, a DNS failure could randomly cause a hang during a push. Solve
|
||||||
|
this by creating a class for a wait group which is abortable and simply
|
||||||
|
abort it if we encounter an error, preventing any deadlocks caused by
|
||||||
|
miscounting the number of items.
|
||||||
|
---
|
||||||
|
tq/transfer_queue.go | 55 ++++++++++++++++++++++++++++++++++----------
|
||||||
|
1 file changed, 43 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tq/transfer_queue.go b/tq/transfer_queue.go
|
||||||
|
index 89296a646..7d39fe581 100644
|
||||||
|
--- a/tq/transfer_queue.go
|
||||||
|
+++ b/tq/transfer_queue.go
|
||||||
|
@@ -123,6 +123,43 @@ func (b batch) Len() int { return len(b) }
|
||||||
|
func (b batch) Less(i, j int) bool { return b[i].Size < b[j].Size }
|
||||||
|
func (b batch) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
|
||||||
|
|
||||||
|
+type abortableWaitGroup struct {
|
||||||
|
+ wq sync.WaitGroup
|
||||||
|
+ counter int
|
||||||
|
+ mu sync.Mutex
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func newAbortableWaitQueue() *abortableWaitGroup {
|
||||||
|
+ return &abortableWaitGroup{}
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func (q *abortableWaitGroup) Add(delta int) {
|
||||||
|
+ q.mu.Lock()
|
||||||
|
+ defer q.mu.Unlock()
|
||||||
|
+
|
||||||
|
+ q.counter += delta
|
||||||
|
+ q.wq.Add(delta)
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func (q *abortableWaitGroup) Done() {
|
||||||
|
+ q.mu.Lock()
|
||||||
|
+ defer q.mu.Unlock()
|
||||||
|
+
|
||||||
|
+ q.counter -= 1
|
||||||
|
+ q.wq.Done()
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func (q *abortableWaitGroup) Abort() {
|
||||||
|
+ q.mu.Lock()
|
||||||
|
+ defer q.mu.Unlock()
|
||||||
|
+
|
||||||
|
+ q.wq.Add(-q.counter)
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+func (q *abortableWaitGroup) Wait() {
|
||||||
|
+ q.wq.Wait()
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
// TransferQueue organises the wider process of uploading and downloading,
|
||||||
|
// including calling the API, passing the actual transfer request to transfer
|
||||||
|
// adapters, and dealing with progress, errors and retries.
|
||||||
|
@@ -150,7 +187,7 @@ type TransferQueue struct {
|
||||||
|
// wait is used to keep track of pending transfers. It is incremented
|
||||||
|
// once per unique OID on Add(), and is decremented when that transfer
|
||||||
|
// is marked as completed or failed, but not retried.
|
||||||
|
- wait sync.WaitGroup
|
||||||
|
+ wait *abortableWaitGroup
|
||||||
|
manifest *Manifest
|
||||||
|
rc *retryCounter
|
||||||
|
|
||||||
|
@@ -250,6 +287,7 @@ func NewTransferQueue(dir Direction, manifest *Manifest, remote string, options
|
||||||
|
trMutex: &sync.Mutex{},
|
||||||
|
manifest: manifest,
|
||||||
|
rc: newRetryCounter(),
|
||||||
|
+ wait: newAbortableWaitQueue(),
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, opt := range options {
|
||||||
|
@@ -401,8 +439,11 @@ func (q *TransferQueue) collectBatches() {
|
||||||
|
collected, closing = q.collectPendingUntil(done)
|
||||||
|
|
||||||
|
// If we've encountered a serious error here, abort immediately;
|
||||||
|
- // don't process further batches.
|
||||||
|
+ // don't process further batches. Abort the wait queue so that
|
||||||
|
+ // we don't deadlock waiting for objects to complete when they
|
||||||
|
+ // never will.
|
||||||
|
if err != nil {
|
||||||
|
+ q.wait.Abort()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -497,11 +538,6 @@ func (q *TransferQueue) enqueueAndCollectRetriesFor(batch batch) (batch, error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- if err != nil && bRes != nil {
|
||||||
|
- // Avoid a hang if we return early.
|
||||||
|
- q.wait.Add(-len(bRes.Objects))
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
return next, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -521,11 +557,6 @@ func (q *TransferQueue) enqueueAndCollectRetriesFor(batch batch) (batch, error)
|
||||||
|
// missing in that case, since we don't need to upload
|
||||||
|
// it.
|
||||||
|
if o.Missing && len(o.Actions) != 0 {
|
||||||
|
- // Indicate that we've handled these objects, in
|
||||||
|
- // this case by ignoring them and aborting
|
||||||
|
- // early. Failing to do this means we deadlock
|
||||||
|
- // on this WaitGroup.
|
||||||
|
- q.wait.Add(-len(bRes.Objects))
|
||||||
|
return nil, errors.Errorf("Unable to find source for object %v (try running git lfs fetch --all)", o.Oid)
|
||||||
|
}
|
||||||
|
}
|
17
git-lfs.spec
17
git-lfs.spec
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# https://github.com/git-lfs/git-lfs
|
# https://github.com/git-lfs/git-lfs
|
||||||
%global goipath github.com/git-lfs/git-lfs
|
%global goipath github.com/git-lfs/git-lfs
|
||||||
Version: 2.7.2
|
Version: 2.8.0
|
||||||
|
|
||||||
%gometa
|
%gometa
|
||||||
|
|
||||||
@ -19,11 +19,14 @@ Summary: Git extension for versioning large files
|
|||||||
|
|
||||||
License: MIT
|
License: MIT
|
||||||
URL: https://git-lfs.github.io/
|
URL: https://git-lfs.github.io/
|
||||||
Source0: %{gosource}
|
Source0: https://github.com/%{name}/%{name}/releases/download/v%{version}/%{name}-v%{version}.tar.gz
|
||||||
|
# https://github.com/git-lfs/git-lfs/issues/3798
|
||||||
|
Patch0001: https://github.com/git-lfs/git-lfs/pull/3800.patch
|
||||||
|
|
||||||
BuildRequires: golang(github.com/git-lfs/gitobj) >= 1.1.0
|
BuildRequires: golang(github.com/git-lfs/gitobj) >= 1.3.1
|
||||||
BuildRequires: golang(github.com/git-lfs/gitobj/errors) >= 1.1.0
|
BuildRequires: golang(github.com/git-lfs/gitobj/errors) >= 1.3.1
|
||||||
BuildRequires: golang(github.com/git-lfs/go-netrc/netrc) >= 0-0.1.20180827gite0e9ca4
|
BuildRequires: golang(github.com/git-lfs/go-netrc/netrc) >= 0-0.1.20180827gite0e9ca4
|
||||||
|
BuildRequires: golang(github.com/git-lfs/go-ntlm/ntlm)
|
||||||
BuildRequires: golang(github.com/git-lfs/wildmatch) >= 1.0.2
|
BuildRequires: golang(github.com/git-lfs/wildmatch) >= 1.0.2
|
||||||
BuildRequires: golang(github.com/kr/pty)
|
BuildRequires: golang(github.com/kr/pty)
|
||||||
BuildRequires: golang(github.com/mattn/go-isatty) >= 0.0.4
|
BuildRequires: golang(github.com/mattn/go-isatty) >= 0.0.4
|
||||||
@ -31,7 +34,6 @@ BuildRequires: golang(github.com/olekukonko/ts)
|
|||||||
BuildRequires: golang(github.com/pkg/errors)
|
BuildRequires: golang(github.com/pkg/errors)
|
||||||
BuildRequires: golang(github.com/rubyist/tracerx)
|
BuildRequires: golang(github.com/rubyist/tracerx)
|
||||||
BuildRequires: golang(github.com/spf13/cobra) >= 0.0.3
|
BuildRequires: golang(github.com/spf13/cobra) >= 0.0.3
|
||||||
BuildRequires: golang(github.com/ThomsonReutersEikon/go-ntlm/ntlm)
|
|
||||||
BuildRequires: golang(golang.org/x/sync/semaphore)
|
BuildRequires: golang(golang.org/x/sync/semaphore)
|
||||||
|
|
||||||
# Generate man pages
|
# Generate man pages
|
||||||
@ -62,6 +64,8 @@ storing the file contents on a remote server.
|
|||||||
%prep
|
%prep
|
||||||
%goprep
|
%goprep
|
||||||
|
|
||||||
|
%patch0001 -p1
|
||||||
|
|
||||||
# Modify Makefile so that it expects binaries where we build them.
|
# Modify Makefile so that it expects binaries where we build them.
|
||||||
sed -i -e 's!\.\./bin/!/%{gobuilddir}/bin/!g' t/Makefile
|
sed -i -e 's!\.\./bin/!/%{gobuilddir}/bin/!g' t/Makefile
|
||||||
|
|
||||||
@ -121,6 +125,9 @@ PATH=%{buildroot}%{_bindir}:%{gobuilddir}/bin:$PATH \
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri Aug 30 2019 Elliott Sales de Andrade <quantum.analyst@gmail.com> - 2.8.0-1
|
||||||
|
- Update to latest version
|
||||||
|
|
||||||
* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 2.7.2-3
|
* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 2.7.2-3
|
||||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
|
||||||
|
|
||||||
|
2
sources
2
sources
@ -1 +1 @@
|
|||||||
SHA512 (git-lfs-2.7.2.tar.gz) = cd71815eb418b7acaf077de4873ff49d332f71151c1212ca4fe3a2d0e079bad873894bb416488f272777153cc3422deecf17a849cd67f150b44eb094a09ae8be
|
SHA512 (git-lfs-v2.8.0.tar.gz) = e30da595dc2302fef692211da2efe93db9803914603229b46f15199ac9b87fe3d604a0436223d9e47f34b70ea2206ebf69b572003ead8d9f81f036c986281e2c
|
||||||
|
Loading…
Reference in New Issue
Block a user