Skip to content

Commit fe5fa24

Browse files
author
Aaron Schlesinger
committed
fix(pkg/gitreceive): move the object polling logic into storage
and use it in build.go. also add tests for the new polling logic
1 parent eb4d2ac commit fe5fa24

4 files changed

Lines changed: 71 additions & 14 deletions

File tree

builder

20.6 MB
Binary file not shown.

pkg/gitreceive/build.go

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020

2121
"k8s.io/kubernetes/pkg/api"
2222
client "k8s.io/kubernetes/pkg/client/unversioned"
23-
"k8s.io/kubernetes/pkg/util/wait"
2423
)
2524

2625
// repoCmd returns exec.Command(first, others...) with its current working directory repoDir
@@ -224,15 +223,13 @@ func build(conf *Config, s3Client *storage.Client, kubeClient *client.Client, fs
224223
slugBuilderInfo.PushKey(),
225224
)
226225
// poll the s3 server to ensure the slug exists
227-
err = wait.PollImmediate(conf.ObjectStorageTickDuration(), conf.ObjectStorageWaitDuration(), func() (bool, error) {
228-
exists, err := storage.ObjectExists(s3Client, conf.Bucket, slugBuilderInfo.PushKey())
229-
if err != nil {
230-
return false, fmt.Errorf("Checking if object %s/%s exists (%s)", conf.Bucket, slugBuilderInfo.PushKey(), err)
231-
}
232-
return exists, nil
233-
})
234-
235-
if err != nil {
226+
if err := storage.WaitForObject(
227+
s3Client,
228+
conf.Bucket,
229+
slugBuilderInfo.PushKey(),
230+
conf.ObjectStorageTickDuration(),
231+
conf.ObjectStorageWaitDuration(),
232+
); err != nil {
236233
return fmt.Errorf("Timed out waiting for object in storage, aborting build (%s)", err)
237234
}
238235
log.Info("Build complete.")

pkg/gitreceive/storage/object.go

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package storage
22

33
import (
4+
"errors"
5+
"fmt"
46
"io"
7+
"time"
58

69
s3 "github.com/minio/minio-go"
710
)
@@ -18,21 +21,54 @@ const (
1821
// - false, err with the appropriate error if the statter failed
1922
// - true, nil if the statter succeeded and reported the object exists
2023
func ObjectExists(statter ObjectStatter, bucketName, objKey string) (bool, error) {
21-
objInfo, err := statter.StatObject(bucketName, objKey)
24+
_, err := statter.StatObject(bucketName, objKey)
2225
if err != nil {
2326
minioErr := s3.ToErrorResponse(err)
2427
if minioErr.Code == noSuchKeyCode {
2528
return false, nil
2629
}
2730
return false, err
2831
}
29-
if objInfo.Err != nil {
30-
return false, nil
31-
}
3232
return true, nil
3333
}
3434

3535
func UploadObject(putter ObjectPutter, bucketName, objKey string, reader io.Reader) error {
3636
_, err := putter.PutObject(bucketName, objKey, reader, octetStream)
3737
return err
3838
}
39+
40+
// WaitForObject checks statter for the object at ${bucketName}/${objKey} right away, then at every tick, then once when the timeout is up.
41+
// Returns nil if it finds the object before or at timeout. Otherwise returns an error
42+
func WaitForObject(statter ObjectStatter, bucketName, objKey string, tick, timeout time.Duration) error {
43+
noExist := errors.New("object doesn't exist")
44+
checker := func() error {
45+
exists, err := ObjectExists(statter, bucketName, objKey)
46+
if err != nil {
47+
return err
48+
} else if exists {
49+
return nil
50+
} else {
51+
return noExist
52+
}
53+
}
54+
if err := checker(); err == nil {
55+
return nil
56+
}
57+
ticker := time.NewTicker(tick)
58+
defer ticker.Stop()
59+
timer := time.NewTimer(timeout)
60+
defer timer.Stop()
61+
for {
62+
select {
63+
case <-ticker.C:
64+
if err := checker(); err == nil {
65+
return nil
66+
}
67+
case <-timer.C:
68+
if err := checker(); err == nil {
69+
return nil
70+
}
71+
return fmt.Errorf("Object %s/%s didn't exist after %s", bucketName, objKey, timeout)
72+
}
73+
}
74+
}

pkg/gitreceive/storage/object_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"io"
66
"strings"
77
"testing"
8+
"time"
89

910
"github.com/arschles/assert"
1011
s3 "github.com/minio/minio-go"
@@ -78,3 +79,26 @@ func TestUploadObjectFailure(t *testing.T) {
7879
assert.Err(t, UploadObject(putter, bucketName, objKey, rdr), err)
7980
assert.Equal(t, len(putter.Calls), 1, "number of calls to PutObject")
8081
}
82+
83+
func TestWaitForObjectMissing(t *testing.T) {
84+
statter := &FakeObjectStatter{
85+
Fn: func(string, string) (s3.ObjectInfo, error) {
86+
return s3.ObjectInfo{}, s3.ErrorResponse{Code: noSuchKeyCode}
87+
},
88+
}
89+
err := WaitForObject(statter, bucketName, objKey, 1*time.Millisecond, 2*time.Millisecond)
90+
assert.True(t, err != nil, "no error received when there should have been")
91+
// it should make 1 call immediately, then calls at 1ms and 2ms
92+
assert.Equal(t, len(statter.Calls), 3, "number of calls to the statter")
93+
}
94+
95+
func TestWaitForObjectExists(t *testing.T) {
96+
statter := &FakeObjectStatter{
97+
Fn: func(string, string) (s3.ObjectInfo, error) {
98+
return s3.ObjectInfo{}, nil
99+
},
100+
}
101+
assert.NoErr(t, WaitForObject(statter, bucketName, objKey, 1*time.Millisecond, 2*time.Millisecond))
102+
// it should make 1 call immediately, then immediateley succeed
103+
assert.Equal(t, len(statter.Calls), 1, "number of calls to the statter")
104+
}

0 commit comments

Comments
 (0)