44 "context"
55 "fmt"
66 "reflect"
7+ "sync"
78 "time"
89
910 "github.com/tarantool/go-tarantool/v2"
@@ -195,28 +196,83 @@ func SetInstanceRO(ctx context.Context, instance pool.Instance, isReplica bool)
195196
196197 req := tarantool .NewCallRequest ("box.cfg" ).
197198 Args ([]interface {}{map [string ]bool {"read_only" : isReplica }})
198- if _ , err := conn .Do (req ).Get (); err != nil {
199- return err
199+ if resp , err := conn .Do (req ).Get (); err != nil {
200+ // return err
201+ return fmt .Errorf ("%w: resp: %v" , err , resp )
200202 }
201203
202204 return nil
203205}
204206
207+ type initPoolHandler struct {
208+ roles map [string ]pool.Role
209+ rolesMutex sync.Mutex
210+ }
211+
212+ func (h * initPoolHandler ) Discovered (name string , conn * tarantool.Connection ,
213+ role pool.Role ) error {
214+ h .rolesMutex .Lock ()
215+ h .roles [name ] = role
216+ h .rolesMutex .Unlock ()
217+ return nil
218+ }
219+
220+ func (h * initPoolHandler ) Deactivated (name string , conn * tarantool.Connection ,
221+ role pool.Role ) error {
222+ h .rolesMutex .Lock ()
223+ delete (h .roles , name )
224+ h .rolesMutex .Unlock ()
225+ return nil
226+ }
227+
205228func SetClusterRO (instances []pool.Instance , roles []bool ) error {
206229 if len (instances ) != len (roles ) {
207230 return fmt .Errorf ("number of instances should be equal to number of roles" )
208231 }
209232
233+ ctx , cancel := context .WithTimeout (context .Background (), 500 * time .Millisecond )
234+
210235 for i , instance := range instances {
211- ctx , cancel := GetConnectContext ()
212- err := SetInstanceRO (ctx , instance , roles [i ])
236+ err := SetInstanceRO (ctx , instance .Dialer , instance .Opts , roles [i ])
213237 cancel ()
214238 if err != nil {
215239 return err
216240 }
217241 }
218242
219- return nil
243+ // if ctx.Done() {
244+ // return nil, ctx.Err()
245+ // }
246+
247+ h := & initPoolHandler {}
248+ initPoolOpts := pool.Opts {
249+ CheckTimeout : 100 * time .Microsecond ,
250+ ConnectionHandler : h ,
251+ }
252+ pool , err := pool .ConnectWithOpts (ctx , instances , initPoolOpts )
253+ if err != nil {
254+ return err
255+ }
256+ defer pool .Close ()
257+
258+ // Prepare roles map that
259+ expectedRoles := make (map [string ]bool , len (roles ))
260+ for i , role := range roles {
261+ expectedRoles [instances [i ].Name ] = role
262+ }
263+
264+ // Wait for the roles to be applied.
265+ for i := 0 ; i < 100 ; i ++ {
266+ h .rolesMutex .Lock ()
267+ if reflect .DeepEqual (h .roles , expectedRoles ) {
268+ h .rolesMutex .Unlock ()
269+ return nil
270+ }
271+ h .rolesMutex .Unlock ()
272+
273+ time .Sleep (100 * time .Millisecond )
274+ }
275+ return fmt .Errorf ("Failed to wait roles are applied" )
220276}
221277
222278func StartTarantoolInstances (instsOpts []StartOpts ) ([]* TarantoolInstance , error ) {
@@ -242,5 +298,5 @@ func StopTarantoolInstances(instances []*TarantoolInstance) {
242298}
243299
244300func GetPoolConnectContext () (context.Context , context.CancelFunc ) {
245- return context .WithTimeout (context .Background (), 500 * time .Millisecond )
301+ return context .WithTimeout (context .Background (), 1000 * time .Millisecond )
246302}
0 commit comments