@@ -360,8 +360,28 @@ func (c *Client) RemoveMember(id uint64) ([]Member, error) {
360
360
defer func () { _ = cli .Close () }()
361
361
362
362
ctx , cancel := context .WithTimeout (context .Background (), etcdTimeout )
363
+ defer cancel ()
364
+
365
+ // List members and quickly return if the member does not exist.
366
+ listResp , err := cli .MemberList (ctx )
367
+ if err != nil {
368
+ klog .V (5 ).Infof ("Failed to check whether the member %s exists: %v" , strconv .FormatUint (id , 16 ), err )
369
+ lastError = err
370
+ return false , nil
371
+ }
372
+ found := false
373
+ for _ , member := range listResp .Members {
374
+ if member .GetID () == id {
375
+ found = true
376
+ break
377
+ }
378
+ }
379
+ if ! found {
380
+ klog .V (5 ).Infof ("Member %s was not found; assuming it was already removed" , strconv .FormatUint (id , 16 ))
381
+ return true , nil
382
+ }
383
+
363
384
resp , err = cli .MemberRemove (ctx , id )
364
- cancel ()
365
385
if err == nil {
366
386
return true , nil
367
387
}
@@ -421,29 +441,40 @@ func (c *Client) addMember(name string, peerAddrs string, isLearner bool) ([]Mem
421
441
var (
422
442
lastError error
423
443
respMembers []* etcdserverpb.Member
424
- learnerID uint64
425
444
resp * clientv3.MemberAddResponse
426
445
)
427
446
err = wait .PollUntilContextTimeout (context .Background (), constants .EtcdAPICallRetryInterval , constants .EtcdAPICallTimeout ,
428
447
true , func (_ context.Context ) (bool , error ) {
429
448
ctx , cancel := context .WithTimeout (context .Background (), etcdTimeout )
430
449
defer cancel ()
431
- if isLearner {
432
- // if learnerID is set, it means the etcd member is already added successfully.
433
- if learnerID == 0 {
434
- klog .V (1 ).Info ("[etcd] Adding etcd member as learner" )
435
- resp , err = cli .MemberAddAsLearner (ctx , []string {peerAddrs })
436
- if err != nil {
437
- lastError = err
438
- return false , nil
439
- }
440
- learnerID = resp .Member .ID
450
+
451
+ // List members and quickly return if the member already exists.
452
+ listResp , err := cli .MemberList (ctx )
453
+ if err != nil {
454
+ klog .V (5 ).Infof ("Failed to check whether the member %q exists: %v" , peerAddrs , err )
455
+ lastError = err
456
+ return false , nil
457
+ }
458
+ found := false
459
+ for _ , member := range listResp .Members {
460
+ if member .GetPeerURLs ()[0 ] == peerAddrs {
461
+ found = true
462
+ break
441
463
}
442
- respMembers = resp .Members
464
+ }
465
+ if found {
466
+ klog .V (5 ).Infof ("The peer URL %q for the added etcd member already exists. Skipping etcd member addition" , peerAddrs )
467
+ respMembers = listResp .Members
443
468
return true , nil
444
469
}
445
470
446
- resp , err = cli .MemberAdd (ctx , []string {peerAddrs })
471
+ if isLearner {
472
+ klog .V (1 ).Infof ("[etcd] Adding etcd member %q as learner" , peerAddrs )
473
+ resp , err = cli .MemberAddAsLearner (ctx , []string {peerAddrs })
474
+ } else {
475
+ klog .V (1 ).Infof ("[etcd] Adding etcd member %q" , peerAddrs )
476
+ resp , err = cli .MemberAdd (ctx , []string {peerAddrs })
477
+ }
447
478
if err == nil {
448
479
respMembers = resp .Members
449
480
return true , nil
0 commit comments