Merge pull request #2957 from yichengq/fix-pipeline-test

rafthttp: fix TestStopBlockedPipeline
This commit is contained in:
Yicheng Qin 2015-06-12 08:03:12 -07:00
commit e46fa0a213
2 changed files with 24 additions and 15 deletions

View File

@ -153,6 +153,7 @@ func (p *pipeline) post(data []byte) (err error) {
select {
case <-done:
case <-p.stopc:
waitSchedule()
stopped = true
if cancel, ok := p.tr.(canceler); ok {
cancel.CancelRequest(req)
@ -199,3 +200,6 @@ func (p *pipeline) post(data []byte) (err error) {
return fmt.Errorf("unexpected http status %s while posting to %q", http.StatusText(resp.StatusCode), req.URL.String())
}
}
// waitSchedule waits other goroutines to be scheduled for a while
func waitSchedule() { time.Sleep(time.Millisecond) }

View File

@ -212,34 +212,39 @@ func TestStopBlockedPipeline(t *testing.T) {
}
type roundTripperBlocker struct {
c chan error
mu sync.Mutex
unblocked bool
unblockc chan struct{}
mu sync.Mutex
cancel map[*http.Request]chan struct{}
}
func newRoundTripperBlocker() *roundTripperBlocker {
return &roundTripperBlocker{c: make(chan error)}
return &roundTripperBlocker{
unblockc: make(chan struct{}),
cancel: make(map[*http.Request]chan struct{}),
}
}
func (t *roundTripperBlocker) RoundTrip(req *http.Request) (*http.Response, error) {
err := <-t.c
if err != nil {
return nil, err
c := make(chan struct{}, 1)
t.mu.Lock()
t.cancel[req] = c
t.mu.Unlock()
select {
case <-t.unblockc:
return &http.Response{StatusCode: http.StatusNoContent, Body: &nopReadCloser{}}, nil
case <-c:
return nil, errors.New("request canceled")
}
return &http.Response{StatusCode: http.StatusNoContent, Body: &nopReadCloser{}}, nil
}
func (t *roundTripperBlocker) unblock() {
t.mu.Lock()
t.unblocked = true
t.mu.Unlock()
close(t.c)
close(t.unblockc)
}
func (t *roundTripperBlocker) CancelRequest(req *http.Request) {
t.mu.Lock()
defer t.mu.Unlock()
if t.unblocked {
return
if c, ok := t.cancel[req]; ok {
c <- struct{}{}
delete(t.cancel, req)
}
t.c <- errors.New("request canceled")
}
type respRoundTripper struct {