Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
caddy
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
caddy
Commits
a7766c90
Commit
a7766c90
authored
Mar 10, 2016
by
Pieter Raubenheimer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add common method for checking host availability
parent
ce8ee831
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
50 additions
and
18 deletions
+50
-18
middleware/proxy/policy.go
middleware/proxy/policy.go
+6
-6
middleware/proxy/policy_test.go
middleware/proxy/policy_test.go
+14
-3
middleware/proxy/proxy.go
middleware/proxy/proxy.go
+11
-0
middleware/proxy/upstream.go
middleware/proxy/upstream.go
+6
-9
middleware/proxy/upstream_test.go
middleware/proxy/upstream_test.go
+13
-0
No files found.
middleware/proxy/policy.go
View file @
a7766c90
...
...
@@ -25,11 +25,11 @@ type Random struct{}
// Select selects an up host at random from the specified pool.
func
(
r
*
Random
)
Select
(
pool
HostPool
)
*
UpstreamHost
{
// instead of just generating a random index
// this is done to prevent selecting a
down
host
// this is done to prevent selecting a
unavailable
host
var
randHost
*
UpstreamHost
count
:=
0
for
_
,
host
:=
range
pool
{
if
host
.
Down
()
{
if
!
host
.
Available
()
{
continue
}
count
++
...
...
@@ -56,7 +56,7 @@ func (r *LeastConn) Select(pool HostPool) *UpstreamHost {
count
:=
0
leastConn
:=
int64
(
1
<<
63
-
1
)
for
_
,
host
:=
range
pool
{
if
host
.
Down
()
{
if
!
host
.
Available
()
{
continue
}
hostConns
:=
host
.
Conns
...
...
@@ -90,11 +90,11 @@ func (r *RoundRobin) Select(pool HostPool) *UpstreamHost {
poolLen
:=
uint32
(
len
(
pool
))
selection
:=
atomic
.
AddUint32
(
&
r
.
Robin
,
1
)
%
poolLen
host
:=
pool
[
selection
]
// if the currently selected host is
down
, just ffwd to up host
for
i
:=
uint32
(
1
);
host
.
Down
()
&&
i
<
poolLen
;
i
++
{
// if the currently selected host is
not available
, just ffwd to up host
for
i
:=
uint32
(
1
);
!
host
.
Available
()
&&
i
<
poolLen
;
i
++
{
host
=
pool
[(
selection
+
i
)
%
poolLen
]
}
if
host
.
Down
()
{
if
!
host
.
Available
()
{
return
nil
}
return
host
...
...
middleware/proxy/policy_test.go
View file @
a7766c90
...
...
@@ -53,12 +53,23 @@ func TestRoundRobinPolicy(t *testing.T) {
if
h
!=
pool
[
2
]
{
t
.
Error
(
"Expected second round robin host to be third host in the pool."
)
}
// mark host as down
pool
[
0
]
.
Unhealthy
=
true
h
=
rrPolicy
.
Select
(
pool
)
if
h
!=
pool
[
1
]
{
if
h
!=
pool
[
0
]
{
t
.
Error
(
"Expected third round robin host to be first host in the pool."
)
}
// mark host as down
pool
[
1
]
.
Unhealthy
=
true
h
=
rrPolicy
.
Select
(
pool
)
if
h
!=
pool
[
2
]
{
t
.
Error
(
"Expected to skip down host."
)
}
// mark host as full
pool
[
2
]
.
Conns
=
1
pool
[
2
]
.
MaxConns
=
1
h
=
rrPolicy
.
Select
(
pool
)
if
h
!=
pool
[
0
]
{
t
.
Error
(
"Expected to skip full host."
)
}
}
func
TestLeastConnPolicy
(
t
*
testing
.
T
)
{
...
...
middleware/proxy/proxy.go
View file @
a7766c90
...
...
@@ -44,6 +44,7 @@ type UpstreamHost struct {
ExtraHeaders
http
.
Header
CheckDown
UpstreamHostDownFunc
WithoutPathPrefix
string
MaxConns
int64
}
// Down checks whether the upstream host is down or not.
...
...
@@ -57,6 +58,16 @@ func (uh *UpstreamHost) Down() bool {
return
uh
.
CheckDown
(
uh
)
}
// Full checks whether the upstream host has reached its maximum connections
func
(
uh
*
UpstreamHost
)
Full
()
bool
{
return
uh
.
MaxConns
>
0
&&
uh
.
Conns
>=
uh
.
MaxConns
}
// Available checks whether the upstream host is available for proxying to
func
(
uh
*
UpstreamHost
)
Available
()
bool
{
return
!
uh
.
Down
()
&&
!
uh
.
Full
()
}
// tryDuration is how long to try upstream hosts; failures result in
// immediate retries until this duration ends or we get a nil host.
var
tryDuration
=
60
*
time
.
Second
...
...
middleware/proxy/upstream.go
View file @
a7766c90
...
...
@@ -80,10 +80,6 @@ func NewStaticUpstreams(c parse.Dispenser) ([]Upstream, error) {
ExtraHeaders
:
upstream
.
proxyHeaders
,
CheckDown
:
func
(
upstream
*
staticUpstream
)
UpstreamHostDownFunc
{
return
func
(
uh
*
UpstreamHost
)
bool
{
if
upstream
.
MaxConns
!=
0
&&
uh
.
Conns
>=
upstream
.
MaxConns
{
return
true
}
if
uh
.
Unhealthy
{
return
true
}
...
...
@@ -95,6 +91,7 @@ func NewStaticUpstreams(c parse.Dispenser) ([]Upstream, error) {
}
}(
upstream
),
WithoutPathPrefix
:
upstream
.
WithoutPathPrefix
,
MaxConns
:
upstream
.
MaxConns
,
}
if
baseURL
,
err
:=
url
.
Parse
(
uh
.
Name
);
err
==
nil
{
uh
.
ReverseProxy
=
NewSingleHostReverseProxy
(
baseURL
,
uh
.
WithoutPathPrefix
)
...
...
@@ -234,19 +231,19 @@ func (u *staticUpstream) HealthCheckWorker(stop chan struct{}) {
func
(
u
*
staticUpstream
)
Select
()
*
UpstreamHost
{
pool
:=
u
.
Hosts
if
len
(
pool
)
==
1
{
if
pool
[
0
]
.
Down
()
{
if
!
pool
[
0
]
.
Available
()
{
return
nil
}
return
pool
[
0
]
}
all
Down
:=
true
all
Unavailable
:=
true
for
_
,
host
:=
range
pool
{
if
!
host
.
Down
()
{
all
Down
=
false
if
host
.
Available
()
{
all
Unavailable
=
false
break
}
}
if
all
Down
{
if
all
Unavailable
{
return
nil
}
...
...
middleware/proxy/upstream_test.go
View file @
a7766c90
...
...
@@ -40,6 +40,19 @@ func TestSelect(t *testing.T) {
if
h
:=
upstream
.
Select
();
h
==
nil
{
t
.
Error
(
"Expected select to not return nil"
)
}
upstream
.
Hosts
[
0
]
.
Conns
=
1
upstream
.
Hosts
[
0
]
.
MaxConns
=
1
upstream
.
Hosts
[
1
]
.
Conns
=
1
upstream
.
Hosts
[
1
]
.
MaxConns
=
1
upstream
.
Hosts
[
2
]
.
Conns
=
1
upstream
.
Hosts
[
2
]
.
MaxConns
=
1
if
h
:=
upstream
.
Select
();
h
!=
nil
{
t
.
Error
(
"Expected select to return nil as all hosts are full"
)
}
upstream
.
Hosts
[
2
]
.
Conns
=
0
if
h
:=
upstream
.
Select
();
h
==
nil
{
t
.
Error
(
"Expected select to not return nil"
)
}
}
func
TestRegisterPolicy
(
t
*
testing
.
T
)
{
...
...
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