@@ -2,8 +2,10 @@ package test_helpers
22
33import (
44 "context"
5+ "errors"
56 "fmt"
67 "reflect"
8+ "sync"
79 "time"
810
911 "github.com/tarantool/go-tarantool/v2"
@@ -206,6 +208,45 @@ func SetInstanceRO(ctx context.Context, dialer tarantool.Dialer, connOpts tarant
206208 return err
207209 }
208210
211+ // Wait for the role to be applied.
212+ for {
213+ time .Sleep (10 * time .Millisecond )
214+
215+ var reason string
216+
217+ data , err := conn .Do (tarantool .NewCallRequest ("box.info" )).Get ()
218+ switch {
219+ case err != nil :
220+ reason = fmt .Sprintf ("failed to get box.info: %s" , err )
221+ case len (data ) < 1 :
222+ reason = "box.info is empty"
223+ default :
224+ status , statusFound := data [0 ].(map [interface {}]interface {})["status" ]
225+ readonly , readonlyFound := data [0 ].(map [interface {}]interface {})["ro" ]
226+ switch {
227+ case ! statusFound :
228+ reason = "box.info.status is missing"
229+ case status != "running" :
230+ reason = fmt .Sprintf ("box.info.status='%s' (waiting for 'running')" , status )
231+ case ! readonlyFound :
232+ reason = "box.info.ro is missing"
233+ case readonly != isReplica :
234+ reason = fmt .Sprintf ("box.info.ro='%v' (waiting for '%v')" , readonly , isReplica )
235+ }
236+ }
237+
238+ if len (reason ) == 0 {
239+ break
240+ }
241+
242+ select {
243+ case <- ctx .Done ():
244+ return fmt .Errorf ("%w: failed to apply role, the last reason: %s" , ctx .Err (), reason )
245+ default :
246+ continue
247+ }
248+ }
249+
209250 return nil
210251}
211252
@@ -215,16 +256,23 @@ func SetClusterRO(dialers []tarantool.Dialer, connOpts tarantool.Opts,
215256 return fmt .Errorf ("number of servers should be equal to number of roles" )
216257 }
217258
259+ ctx , cancel := GetConnectContext ()
260+ defer cancel ()
261+
262+ // Apply roles in parallel.
263+ errs := make ([]error , len (dialers ))
264+ var wg sync.WaitGroup
218265 for i , dialer := range dialers {
219- ctx , cancel := GetConnectContext ( )
220- err := SetInstanceRO ( ctx , dialer , connOpts , roles [ i ])
221- cancel ()
222- if err != nil {
223- return err
224- }
266+ wg . Add ( 1 )
267+ // Pass loop variables to avoid its closure.
268+ go func ( i int , dialer tarantool. Dialer ) {
269+ defer wg . Done ()
270+ errs [ i ] = SetInstanceRO ( ctx , dialer , connOpts , roles [ i ])
271+ }( i , dialer )
225272 }
273+ wg .Wait ()
226274
227- return nil
275+ return errors . Join ( errs ... )
228276}
229277
230278func StartTarantoolInstances (instsOpts []StartOpts ) ([]* TarantoolInstance , error ) {
0 commit comments