// TabletExternallyReparented updates all topo records so the current // tablet is the new master for this shard. It is called by the RPC // server. func TabletExternallyReparented(ts topo.Server, tabletAlias topo.TabletAlias, actionTimeout, lockTimeout time.Duration) error { // we're apprently not the master yet, so let's do the work tablet, err := ts.GetTablet(tabletAlias) if err != nil { return err } // fast quick check on the shard shardInfo, err := ts.GetShard(tablet.Keyspace, tablet.Shard) if err != nil { return err } if shardInfo.MasterAlias == tabletAlias { return nil } // grab the shard lock actionNode := actionnode.ShardExternallyReparented(tabletAlias) interrupted := make(chan struct{}) lockPath, err := actionNode.LockShard(ts, tablet.Keyspace, tablet.Shard, lockTimeout, interrupted) if err != nil { return err } // do the work err = tabletExternallyReparentedLocked(ts, tablet, actionTimeout, lockTimeout, interrupted) // release the lock in any case return actionNode.UnlockShard(ts, tablet.Keyspace, tablet.Shard, lockPath, err) }
func (wr *Wrangler) ShardExternallyReparented(keyspace, shard string, masterElectTabletAlias topo.TabletAlias) error { // grab the shard lock actionNode := actionnode.ShardExternallyReparented(masterElectTabletAlias) lockPath, err := wr.lockShard(keyspace, shard, actionNode) if err != nil { return err } // do the work err = wr.shardExternallyReparentedLocked(keyspace, shard, masterElectTabletAlias) // release the lock in any case return wr.unlockShard(keyspace, shard, actionNode, lockPath, err) }
func (wr *Wrangler) ShardExternallyReparented(keyspace, shard string, masterElectTabletAlias topo.TabletAlias, scrapStragglers, continueOnUnexpectedMaster bool, acceptSuccessPercents int) error { // grab the shard lock actionNode := actionnode.ShardExternallyReparented(masterElectTabletAlias) lockPath, err := wr.lockShard(keyspace, shard, actionNode) if err != nil { return err } // do the work err = wr.shardExternallyReparentedLocked(keyspace, shard, masterElectTabletAlias, scrapStragglers, continueOnUnexpectedMaster, acceptSuccessPercents) // release the lock in any case return wr.unlockShard(keyspace, shard, actionNode, lockPath, err) }
// TabletExternallyReparented updates all topo records so the current // tablet is the new master for this shard. // Should be called under RpcWrapLock. func (agent *ActionAgent) TabletExternallyReparented(actionTimeout time.Duration) error { tablet := agent.Tablet() // fast quick check on the shard to see if we're not the master already shardInfo, err := agent.TopoServer.GetShard(tablet.Keyspace, tablet.Shard) if err != nil { log.Warningf("TabletExternallyReparented: Cannot read the shard %v/%v: %v", tablet.Keyspace, tablet.Shard, err) return err } if shardInfo.MasterAlias == agent.TabletAlias { // we are already the master, nothing more to do. return nil } // grab the shard lock actionNode := actionnode.ShardExternallyReparented(agent.TabletAlias) interrupted := make(chan struct{}) lockPath, err := actionNode.LockShard(agent.TopoServer, tablet.Keyspace, tablet.Shard, agent.LockTimeout, interrupted) if err != nil { log.Warningf("TabletExternallyReparented: Cannot lock shard %v/%v: %v", tablet.Keyspace, tablet.Shard, err) return err } // do the work runAfterAction, err := agent.tabletExternallyReparentedLocked(actionTimeout, interrupted) if err != nil { log.Warningf("TabletExternallyReparented: internal error: %v", err) } // release the lock in any case, and run refreshTablet if necessary err = actionNode.UnlockShard(agent.TopoServer, tablet.Keyspace, tablet.Shard, lockPath, err) if runAfterAction { if refreshErr := agent.refreshTablet("RPC(TabletExternallyReparented)"); refreshErr != nil { if err == nil { // no error yet, now we have one err = refreshErr } else { //have an error already, keep the original one log.Warningf("refreshTablet failed with error: %v", refreshErr) } } } return err }