Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
a50f8034
Commit
a50f8034
authored
Dec 18, 2014
by
Daniel Smith
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3037 from smarterclayton/hide_spurious_watch_errors
When connections are broken on Watch, write fewer errors to logs
parents
3ade280f
b2434de7
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
103 additions
and
1 deletion
+103
-1
reflector.go
pkg/client/cache/reflector.go
+1
-1
request.go
pkg/client/request.go
+23
-0
request_test.go
pkg/client/request_test.go
+46
-0
watch.go
pkg/watch/watch.go
+20
-0
watch_test.go
pkg/watch/watch_test.go
+13
-0
No files found.
pkg/client/cache/reflector.go
View file @
a50f8034
...
@@ -172,7 +172,7 @@ func (r *Reflector) watchHandler(w watch.Interface, resourceVersion *string) err
...
@@ -172,7 +172,7 @@ func (r *Reflector) watchHandler(w watch.Interface, resourceVersion *string) err
watchDuration
:=
time
.
Now
()
.
Sub
(
start
)
watchDuration
:=
time
.
Now
()
.
Sub
(
start
)
if
watchDuration
<
1
*
time
.
Second
&&
eventCount
==
0
{
if
watchDuration
<
1
*
time
.
Second
&&
eventCount
==
0
{
glog
.
Errorf
(
"u
nexpected watch close - watch lasted less than a second and no items received"
)
glog
.
V
(
4
)
.
Infof
(
"U
nexpected watch close - watch lasted less than a second and no items received"
)
return
errors
.
New
(
"very short watch"
)
return
errors
.
New
(
"very short watch"
)
}
}
glog
.
V
(
4
)
.
Infof
(
"Watch close - %v total %v items received"
,
r
.
expectedType
,
eventCount
)
glog
.
V
(
4
)
.
Infof
(
"Watch close - %v total %v items received"
,
r
.
expectedType
,
eventCount
)
...
...
pkg/client/request.go
View file @
a50f8034
...
@@ -25,6 +25,7 @@ import (
...
@@ -25,6 +25,7 @@ import (
"net/url"
"net/url"
"path"
"path"
"strconv"
"strconv"
"strings"
"time"
"time"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
...
@@ -298,6 +299,9 @@ func (r *Request) Watch() (watch.Interface, error) {
...
@@ -298,6 +299,9 @@ func (r *Request) Watch() (watch.Interface, error) {
}
}
resp
,
err
:=
client
.
Do
(
req
)
resp
,
err
:=
client
.
Do
(
req
)
if
err
!=
nil
{
if
err
!=
nil
{
if
isProbableEOF
(
err
)
{
return
watch
.
NewEmptyWatch
(),
nil
}
return
nil
,
err
return
nil
,
err
}
}
if
resp
.
StatusCode
!=
http
.
StatusOK
{
if
resp
.
StatusCode
!=
http
.
StatusOK
{
...
@@ -310,6 +314,25 @@ func (r *Request) Watch() (watch.Interface, error) {
...
@@ -310,6 +314,25 @@ func (r *Request) Watch() (watch.Interface, error) {
return
watch
.
NewStreamWatcher
(
watchjson
.
NewDecoder
(
resp
.
Body
,
r
.
codec
)),
nil
return
watch
.
NewStreamWatcher
(
watchjson
.
NewDecoder
(
resp
.
Body
,
r
.
codec
)),
nil
}
}
// isProbableEOF returns true if the given error resembles a connection termination
// scenario that would justify assuming that the watch is empty. The watch stream
// mechanism handles many common partial data errors, so closed connections can be
// retried in many cases.
func
isProbableEOF
(
err
error
)
bool
{
if
uerr
,
ok
:=
err
.
(
*
url
.
Error
);
ok
{
err
=
uerr
.
Err
}
switch
{
case
err
==
io
.
EOF
:
return
true
case
err
.
Error
()
==
"http: can't write HTTP request on broken connection"
:
return
true
case
strings
.
Contains
(
err
.
Error
(),
"connection reset by peer"
)
:
return
true
}
return
false
}
// Stream formats and executes the request, and offers streaming of the response.
// Stream formats and executes the request, and offers streaming of the response.
// Returns io.ReadCloser which could be used for streaming of the response, or an error
// Returns io.ReadCloser which could be used for streaming of the response, or an error
func
(
r
*
Request
)
Stream
()
(
io
.
ReadCloser
,
error
)
{
func
(
r
*
Request
)
Stream
()
(
io
.
ReadCloser
,
error
)
{
...
...
pkg/client/request_test.go
View file @
a50f8034
...
@@ -20,6 +20,7 @@ import (
...
@@ -20,6 +20,7 @@ import (
"bytes"
"bytes"
"encoding/base64"
"encoding/base64"
"errors"
"errors"
"io"
"io/ioutil"
"io/ioutil"
"net/http"
"net/http"
"net/http/httptest"
"net/http/httptest"
...
@@ -164,6 +165,7 @@ func TestRequestWatch(t *testing.T) {
...
@@ -164,6 +165,7 @@ func TestRequestWatch(t *testing.T) {
testCases
:=
[]
struct
{
testCases
:=
[]
struct
{
Request
*
Request
Request
*
Request
Err
bool
Err
bool
Empty
bool
}{
}{
{
{
Request
:
&
Request
{
err
:
errors
.
New
(
"bail"
)},
Request
:
&
Request
{
err
:
errors
.
New
(
"bail"
)},
...
@@ -191,15 +193,59 @@ func TestRequestWatch(t *testing.T) {
...
@@ -191,15 +193,59 @@ func TestRequestWatch(t *testing.T) {
},
},
Err
:
true
,
Err
:
true
,
},
},
{
Request
:
&
Request
{
client
:
clientFunc
(
func
(
req
*
http
.
Request
)
(
*
http
.
Response
,
error
)
{
return
nil
,
io
.
EOF
}),
baseURL
:
&
url
.
URL
{},
},
Empty
:
true
,
},
{
Request
:
&
Request
{
client
:
clientFunc
(
func
(
req
*
http
.
Request
)
(
*
http
.
Response
,
error
)
{
return
nil
,
&
url
.
Error
{
Err
:
io
.
EOF
}
}),
baseURL
:
&
url
.
URL
{},
},
Empty
:
true
,
},
{
Request
:
&
Request
{
client
:
clientFunc
(
func
(
req
*
http
.
Request
)
(
*
http
.
Response
,
error
)
{
return
nil
,
errors
.
New
(
"http: can't write HTTP request on broken connection"
)
}),
baseURL
:
&
url
.
URL
{},
},
Empty
:
true
,
},
{
Request
:
&
Request
{
client
:
clientFunc
(
func
(
req
*
http
.
Request
)
(
*
http
.
Response
,
error
)
{
return
nil
,
errors
.
New
(
"foo: connection reset by peer"
)
}),
baseURL
:
&
url
.
URL
{},
},
Empty
:
true
,
},
}
}
for
i
,
testCase
:=
range
testCases
{
for
i
,
testCase
:=
range
testCases
{
watch
,
err
:=
testCase
.
Request
.
Watch
()
watch
,
err
:=
testCase
.
Request
.
Watch
()
hasErr
:=
err
!=
nil
hasErr
:=
err
!=
nil
if
hasErr
!=
testCase
.
Err
{
if
hasErr
!=
testCase
.
Err
{
t
.
Errorf
(
"%d: expected %t, got %t: %v"
,
i
,
testCase
.
Err
,
hasErr
,
err
)
t
.
Errorf
(
"%d: expected %t, got %t: %v"
,
i
,
testCase
.
Err
,
hasErr
,
err
)
continue
}
}
if
hasErr
&&
watch
!=
nil
{
if
hasErr
&&
watch
!=
nil
{
t
.
Errorf
(
"%d: watch should be nil when error is returned"
,
i
)
t
.
Errorf
(
"%d: watch should be nil when error is returned"
,
i
)
continue
}
if
testCase
.
Empty
{
_
,
ok
:=
<-
watch
.
ResultChan
()
if
ok
{
t
.
Errorf
(
"%d: expected the watch to be empty: %#v"
,
watch
)
}
}
}
}
}
}
}
...
...
pkg/watch/watch.go
View file @
a50f8034
...
@@ -56,6 +56,26 @@ type Event struct {
...
@@ -56,6 +56,26 @@ type Event struct {
Object
runtime
.
Object
Object
runtime
.
Object
}
}
type
emptyWatch
chan
Event
// NewEmptyWatch returns a watch interface that returns no results and is closed.
// May be used in certain error conditions where no information is available but
// an error is not warranted.
func
NewEmptyWatch
()
Interface
{
ch
:=
make
(
chan
Event
)
close
(
ch
)
return
emptyWatch
(
ch
)
}
// Stop implements Interface
func
(
w
emptyWatch
)
Stop
()
{
}
// ResultChan implements Interface
func
(
w
emptyWatch
)
ResultChan
()
<-
chan
Event
{
return
chan
Event
(
w
)
}
// FakeWatcher lets you test anything that consumes a watch.Interface; threadsafe.
// FakeWatcher lets you test anything that consumes a watch.Interface; threadsafe.
type
FakeWatcher
struct
{
type
FakeWatcher
struct
{
result
chan
Event
result
chan
Event
...
...
pkg/watch/watch_test.go
View file @
a50f8034
...
@@ -70,3 +70,16 @@ func TestFake(t *testing.T) {
...
@@ -70,3 +70,16 @@ func TestFake(t *testing.T) {
go
sender
()
go
sender
()
consumer
(
f
)
consumer
(
f
)
}
}
func
TestEmpty
(
t
*
testing
.
T
)
{
w
:=
NewEmptyWatch
()
_
,
ok
:=
<-
w
.
ResultChan
()
if
ok
{
t
.
Errorf
(
"unexpected result channel result"
)
}
w
.
Stop
()
_
,
ok
=
<-
w
.
ResultChan
()
if
ok
{
t
.
Errorf
(
"unexpected result channel result"
)
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment