Skip to content

Commit fe49f2a

Browse files
authored
Merge pull request #523 from orozery/peer-multiple-gateways
controlplane/peer/client: Issue requests in parallel
2 parents d591fac + 0c1d041 commit fe49f2a

File tree

2 files changed

+63
-27
lines changed

2 files changed

+63
-27
lines changed

pkg/controlplane/peer/client.go

Lines changed: 61 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"errors"
2020
"fmt"
2121
"net/http"
22+
"sync"
2223

2324
"github.com/sirupsen/logrus"
2425

@@ -44,24 +45,63 @@ type RemoteServerAuthorizationResponse struct {
4445
AccessToken string
4546
}
4647

47-
// authorize a request for accessing a peer exported service, yielding an access token.
48-
func (c *Client) Authorize(req *api.AuthorizationRequest) (*RemoteServerAuthorizationResponse, error) {
49-
body, err := json.Marshal(req)
50-
if err != nil {
51-
return nil, fmt.Errorf("unable to serialize authorization request: %w", err)
48+
// getResponse tries all gateways in parallel for a response.
49+
// The first successful response is returned.
50+
// If all responses failed, a joined error of all responses is returned.
51+
func (c *Client) getResponse(
52+
getRespFunc func(client *jsonapi.Client) (*jsonapi.Response, error),
53+
) (*jsonapi.Response, error) {
54+
if len(c.clients) == 1 {
55+
return getRespFunc(c.clients[0])
5256
}
5357

54-
var serverResp *jsonapi.Response
58+
results := make(chan struct {
59+
*jsonapi.Response
60+
error
61+
})
62+
var done bool
63+
var lock sync.Mutex
5564
for _, client := range c.clients {
56-
serverResp, err = client.Post(api.RemotePeerAuthorizationPath, body)
57-
if err == nil {
58-
break
65+
go func(currClient *jsonapi.Client) {
66+
resp, err := getRespFunc(currClient)
67+
lock.Lock()
68+
defer lock.Unlock()
69+
if done {
70+
return
71+
}
72+
results <- struct {
73+
*jsonapi.Response
74+
error
75+
}{resp, err}
76+
}(client)
77+
}
78+
79+
var retErr error
80+
for range c.clients {
81+
result := <-results
82+
if result.error == nil {
83+
lock.Lock()
84+
done = true
85+
lock.Unlock()
86+
return result.Response, nil
5987
}
6088

61-
c.logger.Errorf("Error authorizing using endpoint %s: %v",
62-
client.ServerURL(), err)
89+
retErr = errors.Join(retErr, result.error)
90+
}
91+
92+
return nil, retErr
93+
}
94+
95+
// Authorize a request for accessing a peer exported service, yielding an access token.
96+
func (c *Client) Authorize(req *api.AuthorizationRequest) (*RemoteServerAuthorizationResponse, error) {
97+
body, err := json.Marshal(req)
98+
if err != nil {
99+
return nil, fmt.Errorf("unable to serialize authorization request: %w", err)
63100
}
64101

102+
serverResp, err := c.getResponse(func(client *jsonapi.Client) (*jsonapi.Response, error) {
103+
return client.Post(api.RemotePeerAuthorizationPath, body)
104+
})
65105
if err != nil {
66106
return nil, err
67107
}
@@ -93,23 +133,19 @@ func (c *Client) Authorize(req *api.AuthorizationRequest) (*RemoteServerAuthoriz
93133

94134
// GetHeartbeat get a heartbeat from other peers.
95135
func (c *Client) GetHeartbeat() error {
96-
var retErr error
97-
for _, client := range c.clients {
98-
serverResp, err := client.Get(api.HeartbeatPath)
99-
if err != nil {
100-
retErr = errors.Join(retErr, err)
101-
continue
102-
}
103-
104-
if serverResp.Status == http.StatusOK {
105-
return nil
106-
}
136+
serverResp, err := c.getResponse(func(client *jsonapi.Client) (*jsonapi.Response, error) {
137+
return client.Get(api.HeartbeatPath)
138+
})
139+
if err != nil {
140+
return err
141+
}
107142

108-
retErr = errors.Join(retErr, fmt.Errorf("unable to get heartbeat (%d), server returned: %s",
109-
serverResp.Status, serverResp.Body))
143+
if serverResp.Status != http.StatusOK {
144+
return fmt.Errorf("unable to get heartbeat (%d), server returned: %s",
145+
serverResp.Status, serverResp.Body)
110146
}
111147

112-
return retErr // Return an error if all client targets are unreachable
148+
return nil
113149
}
114150

115151
// NewClient returns a new Peer API client.

tests/e2e/k8s/test_peer.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ func (s *TestSuite) TestPeerMultipleGateways() {
105105
require.Equal(s.T(), cl[0].Name(), data)
106106

107107
// verify that the bad gateway does not effect access
108-
for i := 0; i < 100; i++ {
108+
for i := 0; i < 10; i++ {
109109
data, err := cl[0].AccessService(httpecho.GetEchoValue, importedService, false, nil)
110110
require.Nil(s.T(), err)
111111
require.Equal(s.T(), cl[0].Name(), data)
@@ -129,7 +129,7 @@ func (s *TestSuite) TestPeerMultipleGateways() {
129129
require.Equal(s.T(), cl[0].Name(), data)
130130

131131
// verify that the bad gateway does not effect access
132-
for i := 0; i < 100; i++ {
132+
for i := 0; i < 10; i++ {
133133
data, err := cl[0].AccessService(httpecho.GetEchoValue, importedService, false, nil)
134134
require.Nil(s.T(), err)
135135
require.Equal(s.T(), cl[0].Name(), data)

0 commit comments

Comments
 (0)