diff --git a/api/object.go b/api/object.go index d8336e7f..64baba44 100644 --- a/api/object.go +++ b/api/object.go @@ -59,19 +59,20 @@ func (o *ObjectResource) Rel(name string) (*LinkRelation, bool) { return rel, ok } -// IsExpired returns true if any of the actions in this object resource have an -// ExpiresAt field that is after the given instant "now". +// IsExpired returns true, and the time of the expired action, if any of the +// actions in this object resource have an ExpiresAt field that is after the +// given instant "now". // // If the object contains no actions, or none of the actions it does contain // have non-zero ExpiresAt fields, the object is not expired. -func (o *ObjectResource) IsExpired(now time.Time) bool { +func (o *ObjectResource) IsExpired(now time.Time) (time.Time, bool) { for _, a := range o.Actions { if !a.ExpiresAt.IsZero() && a.ExpiresAt.Before(now) { - return true + return a.ExpiresAt, true } } - return false + return time.Time{}, false } func (o *ObjectResource) NeedsAuth() bool { diff --git a/api/object_test.go b/api/object_test.go index 9aed52e4..a3e146b8 100644 --- a/api/object_test.go +++ b/api/object_test.go @@ -14,7 +14,8 @@ func TestObjectsWithNoActionsAreNotExpired(t *testing.T) { Actions: map[string]*api.LinkRelation{}, } - assert.False(t, o.IsExpired(time.Now())) + _, expired := o.IsExpired(time.Now()) + assert.False(t, expired) } func TestObjectsWithZeroValueTimesAreNotExpired(t *testing.T) { @@ -28,7 +29,8 @@ func TestObjectsWithZeroValueTimesAreNotExpired(t *testing.T) { }, } - assert.False(t, o.IsExpired(time.Now())) + _, expired := o.IsExpired(time.Now()) + assert.False(t, expired) } func TestObjectsWithExpirationDatesAreExpired(t *testing.T) { @@ -45,5 +47,7 @@ func TestObjectsWithExpirationDatesAreExpired(t *testing.T) { }, } - assert.True(t, o.IsExpired(now)) + expiredAt, expired := o.IsExpired(now) + assert.Equal(t, expires, expiredAt) + assert.True(t, expired) } diff --git a/transfer/adapterbase.go b/transfer/adapterbase.go index 432c9e94..2b9f6b7f 100644 --- a/transfer/adapterbase.go +++ b/transfer/adapterbase.go @@ -124,11 +124,18 @@ func (a *adapterBase) worker(workerNum int, ctx interface{}) { } tracerx.Printf("xfer: adapter %q worker %d processing job for %q", a.Name(), workerNum, t.Object.Oid) + // tt is the time that we are to compare the transfer's + // `expired_at` property against. + tt := time.Now().Add(-objectExpirationGracePeriod) + // Actual transfer happens here var err error - if t.Object.IsExpired(time.Now().Add(objectExpirationGracePeriod)) { + if expAt, expired := t.Object.IsExpired(tt); expired { tracerx.Printf("xfer: adapter %q worker %d found job for %q expired, retrying...", a.Name(), workerNum, t.Object.Oid) - err = errors.NewRetriableError(errors.Errorf("lfs/transfer: object %q has expired", t.Object.Oid)) + err = errors.NewRetriableError(errors.Errorf( + "lfs/transfer: object %q has expired at %s, %s ago", + t.Object.Oid, expAt, tt.Sub(expAt), + )) } else if t.Object.Size < 0 { tracerx.Printf("xfer: adapter %q worker %d found invalid size for %q (got: %d), retrying...", a.Name(), workerNum, t.Object.Oid, t.Object.Size) err = fmt.Errorf("Git LFS: object %q has invalid size (got: %d)", t.Object.Oid, t.Object.Size)