Skip to content

Commit 42cf393

Browse files
committedJul 19, 2018
Added force option
1 parent 81297ad commit 42cf393

File tree

5 files changed

+86
-53
lines changed

5 files changed

+86
-53
lines changed
 

‎client/api.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@ type API interface {
5151
Shutdown(ctx context.Context, goodbye bool) error
5252

5353
// RemovePeer removes a peer with given ID from the starter cluster.
54-
RemovePeer(ctx context.Context, id string) error
54+
// The removal tries to cleanout & properly shutdown servers first.
55+
// If that does not succeed, the operation returns an error,
56+
// unless force is set to true.
57+
RemovePeer(ctx context.Context, id string, force bool) error
5558

5659
// StartDatabaseUpgrade is called to start the upgrade process
5760
StartDatabaseUpgrade(ctx context.Context) error

‎client/client.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,15 @@ type GoodbyeRequest struct {
205205
}
206206

207207
// RemovePeer removes a peer with given ID from the starter cluster.
208-
func (c *client) RemovePeer(ctx context.Context, id string) error {
209-
url := c.createURL("/goodbye", nil)
208+
// The removal tries to cleanout & properly shutdown servers first.
209+
// If that does not succeed, the operation returns an error,
210+
// unless force is set to true.
211+
func (c *client) RemovePeer(ctx context.Context, id string, force bool) error {
212+
q := url.Values{}
213+
if force {
214+
q.Set("force", "true")
215+
}
216+
url := c.createURL("/goodbye", q)
210217

211218
input := GoodbyeRequest{
212219
SlaveID: id,

‎remove.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,15 @@ var (
4242
removeStarterOptions struct {
4343
starterEndpoint string
4444
starterID string
45+
force bool
4546
}
4647
)
4748

4849
func init() {
4950
f := cmdRemoveStarter.Flags()
5051
f.StringVar(&removeStarterOptions.starterEndpoint, "starter.endpoint", "", "The endpoint of the starter to connect to. E.g. http://localhost:8528")
5152
f.StringVar(&removeStarterOptions.starterID, "starter.id", "", "The ID of the starter to remove")
53+
f.BoolVar(&removeStarterOptions.force, "force", false, "If set to true, the starter will be removed even if the servers cannot be properly shutdown")
5254

5355
cmdMain.AddCommand(cmdRemove)
5456
cmdRemove.AddCommand(cmdRemoveStarter)
@@ -80,7 +82,7 @@ func cmdRemoveStarterRun(cmd *cobra.Command, args []string) {
8082
}
8183
} else {
8284
// Remove another starter from the cluster
83-
if err := c.RemovePeer(ctx, removeStarterOptions.starterID); err != nil {
85+
if err := c.RemovePeer(ctx, removeStarterOptions.starterID, removeStarterOptions.force); err != nil {
8486
log.Fatal().Err(err).Msg("Removing starter from cluster failed")
8587
} else {
8688
log.Info().Msg("Starter has been removed from cluster")

‎service/server.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ type httpServerContext interface {
102102

103103
// HandleGoodbye removes the database servers started by the peer with given id
104104
// from the cluster and alters the cluster configuration, removing the peer.
105-
HandleGoodbye(id string) (peerRemoved bool, err error)
105+
HandleGoodbye(id string, force bool) (peerRemoved bool, err error)
106106

107107
// Called by an agency callback
108108
MasterChangedCallback()
@@ -259,6 +259,7 @@ func (s *httpServer) goodbyeHandler(w http.ResponseWriter, r *http.Request) {
259259
}
260260

261261
// Parse request
262+
force, _ := strconv.ParseBool(r.FormValue("force"))
262263
var req client.GoodbyeRequest
263264
defer r.Body.Close()
264265
body, err := ioutil.ReadAll(r.Body)
@@ -291,7 +292,7 @@ func (s *httpServer) goodbyeHandler(w http.ResponseWriter, r *http.Request) {
291292
if err != nil {
292293
handleError(w, err)
293294
} else {
294-
if err := c.RemovePeer(ctx, req.SlaveID); err != nil {
295+
if err := c.RemovePeer(ctx, req.SlaveID, force); err != nil {
295296
s.log.Debug().Err(err).Msg("Forwarding RemovePeer failed")
296297
handleError(w, err)
297298
} else {
@@ -304,8 +305,8 @@ func (s *httpServer) goodbyeHandler(w http.ResponseWriter, r *http.Request) {
304305
}
305306
} else {
306307
// Remove the peer
307-
s.log.Info().Msgf("Goodbye requested for peer %s", req.SlaveID)
308-
if removed, err := s.context.HandleGoodbye(req.SlaveID); err != nil {
308+
s.log.Info().Bool("force", force).Msgf("Goodbye requested for peer %s", req.SlaveID)
309+
if removed, err := s.context.HandleGoodbye(req.SlaveID, force); err != nil {
309310
// Failure
310311
handleError(w, err)
311312
} else if !removed {

‎service/service.go

+65-45
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ func (s *Service) IsRunningMaster() (isRunningMaster, isRunning bool, masterURL
291291

292292
// HandleGoodbye removes the database servers started by the peer with given id
293293
// from the cluster and alters the cluster configuration, removing the peer.
294-
func (s *Service) HandleGoodbye(id string) (peerRemoved bool, err error) {
294+
func (s *Service) HandleGoodbye(id string, force bool) (peerRemoved bool, err error) {
295295
// Find peer
296296
s.mutex.Lock()
297297
peer, peerFound := s.myPeers.PeerByID(id)
@@ -320,59 +320,79 @@ func (s *Service) HandleGoodbye(id string) (peerRemoved bool, err error) {
320320

321321
// Remove dbserver from cluster (if any)
322322
if peer.HasDBServer() {
323-
// Find id of dbserver
324-
s.log.Info().Msg("Finding server ID of dbserver")
325-
sc, err := peer.CreateDBServerAPI(s.CreateClient)
326-
if err != nil {
327-
return false, maskAny(err)
328-
}
329-
sid, err := sc.ServerID(ctx)
330-
if err != nil {
331-
return false, maskAny(err)
332-
}
333-
// Clean out DB server
334-
s.log.Info().Msgf("Starting cleanout of dbserver %s", sid)
335-
if err := c.CleanOutServer(ctx, sid); err != nil {
336-
s.log.Warn().Err(err).Msgf("Cleanout requested of dbserver %s failed", sid)
337-
return false, maskAny(err)
323+
shutdownServer := func() error {
324+
// Find id of dbserver
325+
s.log.Info().Msg("Finding server ID of dbserver")
326+
sc, err := peer.CreateDBServerAPI(s.CreateClient)
327+
if err != nil {
328+
return maskAny(err)
329+
}
330+
sid, err := sc.ServerID(ctx)
331+
if err != nil {
332+
return maskAny(err)
333+
}
334+
// Clean out DB server
335+
s.log.Info().Msgf("Starting cleanout of dbserver %s", sid)
336+
if err := c.CleanOutServer(ctx, sid); err != nil {
337+
s.log.Warn().Err(err).Msgf("Cleanout requested of dbserver %s failed", sid)
338+
return maskAny(err)
339+
}
340+
// Wait until server is cleaned out
341+
s.log.Info().Msgf("Waiting for cleanout of dbserver %s to finish", sid)
342+
for {
343+
if cleanedOut, err := c.IsCleanedOut(ctx, sid); err != nil {
344+
s.log.Warn().Err(err).Msgf("IsCleanedOut request of dbserver %s failed", sid)
345+
return maskAny(err)
346+
} else if cleanedOut {
347+
break
348+
}
349+
// Wait a bit
350+
time.Sleep(time.Millisecond * 250)
351+
}
352+
// Remove dbserver from cluster
353+
s.log.Info().Msgf("Removing dbserver %s from cluster", sid)
354+
if err := sc.Shutdown(ctx, true); err != nil {
355+
s.log.Warn().Err(err).Msgf("Shutdown request of dbserver %s failed", sid)
356+
return maskAny(err)
357+
}
358+
return nil
338359
}
339-
// Wait until server is cleaned out
340-
s.log.Info().Msgf("Waiting for cleanout of dbserver %s to finish", sid)
341-
for {
342-
if cleanedOut, err := c.IsCleanedOut(ctx, sid); err != nil {
343-
s.log.Warn().Err(err).Msgf("IsCleanedOut request of dbserver %s failed", sid)
360+
if err := shutdownServer(); err != nil {
361+
if force {
362+
s.log.Warn().Err(err).Msg("Failed to properly shutdown dbserver, removing peer anyway")
363+
} else {
344364
return false, maskAny(err)
345-
} else if cleanedOut {
346-
break
347365
}
348-
// Wait a bit
349-
time.Sleep(time.Millisecond * 250)
350-
}
351-
// Remove dbserver from cluster
352-
s.log.Info().Msgf("Removing dbserver %s from cluster", sid)
353-
if err := sc.Shutdown(ctx, true); err != nil {
354-
s.log.Warn().Err(err).Msgf("Shutdown request of dbserver %s failed", sid)
355-
return false, maskAny(err)
356366
}
357367
}
358368

359369
// Remove coordinator from cluster (if any)
360370
if peer.HasCoordinator() {
361-
// Find id of coordinator
362-
s.log.Info().Msg("Finding server ID of coordinator")
363-
sc, err := peer.CreateCoordinatorAPI(s.CreateClient)
364-
if err != nil {
365-
return false, maskAny(err)
366-
}
367-
sid, err := sc.ServerID(ctx)
368-
if err != nil {
369-
return false, maskAny(err)
371+
shutdownServer := func() error {
372+
// Find id of coordinator
373+
s.log.Info().Msg("Finding server ID of coordinator")
374+
sc, err := peer.CreateCoordinatorAPI(s.CreateClient)
375+
if err != nil {
376+
return maskAny(err)
377+
}
378+
sid, err := sc.ServerID(ctx)
379+
if err != nil {
380+
return maskAny(err)
381+
}
382+
// Remove coordinator from cluster
383+
s.log.Info().Msgf("Removing coordinator %s from cluster", sid)
384+
if err := sc.Shutdown(ctx, true); err != nil {
385+
s.log.Warn().Err(err).Msgf("Shutdown request of coordinator %s failed", sid)
386+
return maskAny(err)
387+
}
388+
return nil
370389
}
371-
// Remove coordinator from cluster
372-
s.log.Info().Msgf("Removing coordinator %s from cluster", sid)
373-
if err := sc.Shutdown(ctx, true); err != nil {
374-
s.log.Warn().Err(err).Msgf("Shutdown request of coordinator %s failed", sid)
375-
return false, maskAny(err)
390+
if err := shutdownServer(); err != nil {
391+
if force {
392+
s.log.Warn().Err(err).Msg("Failed to properly shutdown coordinator, removing peer anyway")
393+
} else {
394+
return false, maskAny(err)
395+
}
376396
}
377397
}
378398

0 commit comments

Comments
 (0)