Skip to content

Commit

Permalink
Merge pull request #36 from stormcat24/feature/improve_update_service
Browse files Browse the repository at this point in the history
Improved process of updating service
  • Loading branch information
Akinori Yamada committed Oct 1, 2015
2 parents b088788 + 893834f commit 6ab0a0f
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 37 deletions.
14 changes: 14 additions & 0 deletions aws/ecs_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,3 +234,17 @@ func (self *EcsApi) DescribeTasks(cluster string, tasks []*string) (*ecs.Describ
}
return result, err
}

func (self *EcsApi) StopTask(cluster string, task string) (*ecs.StopTaskOutput, error) {

params := &ecs.StopTaskInput{
Cluster: aws.String(cluster),
Task: aws.String(task),
}

result, err := self.service.StopTask(params)
if isRateExceeded(err) {
return self.StopTask(cluster, task)
}
return result, err
}
137 changes: 100 additions & 37 deletions service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,60 +181,123 @@ func (self *ServiceController) ApplyServicePlan(plan *ServiceUpdatePlan) error {

api := self.manager.EcsApi()

currentSizeMap := make(map[string]int64, 0)

// currentにあってnewにない(削除)
for _, current := range plan.CurrentServices {
currentSizeMap[*current.ServiceName] = *current.DesiredCount
if _, ok := plan.NewServices[*current.ServiceName]; !ok {
logger.Main.Infof("Delating '%s' service on '%s' ...", *current.ServiceName, plan.Name)

// set desired_count = 0
if _, err := api.UpdateService(plan.Name, *current.ServiceName, 0, *current.TaskDefinition); err != nil {
return err
}
// set desired_count = 0
if _, err := api.UpdateService(plan.Name, *current.ServiceName, 0, *current.TaskDefinition); err != nil {
return err
}
logger.Main.Infof("Updated desired count = 0 of '%s' service on '%s' ...", *current.ServiceName, plan.Name)

// wait to stop service
logger.Main.Infof("Waiting to stop '%s' service on '%s' ...", *current.ServiceName, plan.Name)
if err := self.waitStoppingService(plan.Name, *current.ServiceName); err != nil {
return err
}
logger.Main.Infof("Stoped '%s' service on '%s'.", *current.ServiceName, plan.Name)
// wait to stop service
logger.Main.Infof("Waiting to stop '%s' service on '%s' ...", *current.ServiceName, plan.Name)
if err := self.waitStoppingService(plan.Name, *current.ServiceName); err != nil {
return err
}
logger.Main.Infof("Stoped '%s' service on '%s'.", *current.ServiceName, plan.Name)

// delete service
result, err := api.DeleteService(plan.Name, *current.ServiceArn)
if err != nil {
return err
}
// delete service
dsrv, err := api.DeleteService(plan.Name, *current.ServiceArn)
if err != nil {
return err
}

if err := self.waitStoppingService(plan.Name, *current.ServiceName); err != nil {
return err
if err := self.waitStoppingService(plan.Name, *current.ServiceName); err != nil {
return err
}

logger.Main.Infof("Deleted service '%s' completely.", *dsrv.Service.ServiceArn)
}
}

logger.Main.Infof("Deleted service '%s'", *result.Service.ServiceArn)
// newにあってcurrentにない(新規追加)
for _, add := range plan.NewServices {
if _, ok := plan.CurrentServices[add.Name]; !ok {
logger.Main.Infof("Creating '%s' service on '%s' ...", add.Name, plan.Name)
csrv, err := api.CreateService(plan.Name, add.Name, add.DesiredCount, toLoadBalancers(&add.LoadBalancers), add.TaskDefinition, add.Role)
if err != nil {
return err
}

logger.Main.Infof("Created service '%s', task-definition is '%s'.", *csrv.Service.ServiceArn, *csrv.Service.TaskDefinition)
if err := self.WaitActiveService(plan.Name, add.Name); err != nil {
return err
}
logger.Main.Infof("Started service '%s' completely.", *csrv.Service.ServiceArn)
}
}

// update
for _, add := range plan.NewServices {
current, ok := plan.CurrentServices[add.Name]
if ok {
logger.Main.Infof("Updating '%s' service on '%s' ...", add.Name, plan.Name)

var nextDesiredCount int64
if add.KeepDesiredCount {
if dc, ok := currentSizeMap[add.Name]; ok {
nextDesiredCount = dc
logger.Main.Infof("Keep DesiredCount %d at '%s'", add.Name, nextDesiredCount)
var nextDesiredCount int64
if add.KeepDesiredCount {
nextDesiredCount = *current.DesiredCount
} else {
nextDesiredCount = add.DesiredCount
logger.Main.Infof("Keep DesiredCount = %d at '%s'", nextDesiredCount, add.Name)
}
} else {
nextDesiredCount = add.DesiredCount
}

result, err := api.CreateService(plan.Name, add.Name, nextDesiredCount, toLoadBalancers(&add.LoadBalancers), add.TaskDefinition, add.Role)
if err != nil {
return err
}
svc, err := api.UpdateService(plan.Name, add.Name, nextDesiredCount, add.TaskDefinition)
if err != nil {
return err
}
logger.Main.Infof("Created service '%s', task-definition is '%s'.", *svc.Service.ServiceArn)
logger.Main.Infof("Launching task definition '%s' ...", *svc.Service.TaskDefinition)

var targetServiceId string
if len(svc.Service.Deployments) > 1 {
for _, dep := range svc.Service.Deployments {
if *dep.Status == "ACTIVE" {
targetServiceId = *dep.Id
}
}
} else {
for _, dep := range svc.Service.Deployments {
targetServiceId = *dep.Id
}
}

tasks, err := api.ListTasks(plan.Name, add.Name)
if err != nil {
return err
}

logger.Main.Infof("Created service '%s'", *result.Service.ServiceArn)
errwas := self.WaitActiveService(plan.Name, add.Name)
if errwas != nil {
return errwas
taskIds := []*string{}
for _, tarn := range tasks.TaskArns {
tokens := strings.Split(*tarn, "/")
if len(tokens) == 2 {
s := tokens[1]
taskIds = append(taskIds, &s)
}
}

dts, err := api.DescribeTasks(plan.Name, taskIds)
if err != nil {
return err
}

for _, t := range dts.Tasks {
if *t.StartedBy == targetServiceId {
if _, err := api.StopTask(plan.Name, *t.TaskArn); err != nil {
return err
}
logger.Main.Infof("Stopped Task '%s'", *t.TaskArn)
}
}

if err := self.WaitActiveService(plan.Name, add.Name); err != nil {
return err
}
logger.Main.Infof("Started service '%s' completely.", *svc.Service.ServiceArn)
}

}

return nil
Expand Down

0 comments on commit 6ab0a0f

Please sign in to comment.