@@ -19,6 +19,7 @@ import (
19
19
"errors"
20
20
"fmt"
21
21
"net/http"
22
+ "sync"
22
23
23
24
"github.com/sirupsen/logrus"
24
25
@@ -44,24 +45,63 @@ type RemoteServerAuthorizationResponse struct {
44
45
AccessToken string
45
46
}
46
47
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 ])
52
56
}
53
57
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
55
64
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
59
87
}
60
88
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 )
63
100
}
64
101
102
+ serverResp , err := c .getResponse (func (client * jsonapi.Client ) (* jsonapi.Response , error ) {
103
+ return client .Post (api .RemotePeerAuthorizationPath , body )
104
+ })
65
105
if err != nil {
66
106
return nil , err
67
107
}
@@ -93,23 +133,19 @@ func (c *Client) Authorize(req *api.AuthorizationRequest) (*RemoteServerAuthoriz
93
133
94
134
// GetHeartbeat get a heartbeat from other peers.
95
135
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
+ }
107
142
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 )
110
146
}
111
147
112
- return retErr // Return an error if all client targets are unreachable
148
+ return nil
113
149
}
114
150
115
151
// NewClient returns a new Peer API client.
0 commit comments