@@ -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.
95135func (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.
0 commit comments