command: trigger still applying cancellations from a channel

This commit is contained in:
Mitchell Hashimoto 2017-03-02 11:15:02 -08:00
parent 17c9a403f2
commit 866de2776e
No known key found for this signature in database
GPG Key ID: 744E147AA52F5B0A
1 changed files with 59 additions and 49 deletions

View File

@ -33,8 +33,12 @@ type UiHook struct {
// uiResourceState tracks the state of a single resource // uiResourceState tracks the state of a single resource
type uiResourceState struct { type uiResourceState struct {
Name string
ResourceId string
Op uiResourceOp Op uiResourceOp
Start time.Time Start time.Time
DoneCh chan struct{} // To be used for cancellation
} }
// uiResourceOp is an enum for operations on a resource // uiResourceOp is an enum for operations on a resource
@ -63,13 +67,6 @@ func (h *UiHook) PreApply(
op = uiResourceCreate op = uiResourceCreate
} }
h.l.Lock()
h.resources[id] = uiResourceState{
Op: op,
Start: time.Now().Round(time.Second),
}
h.l.Unlock()
var operation string var operation string
switch op { switch op {
case uiResourceModify: case uiResourceModify:
@ -131,8 +128,9 @@ func (h *UiHook) PreApply(
attrString = "\n " + attrString attrString = "\n " + attrString
} }
var stateIdSuffix string var stateId, stateIdSuffix string
if s != nil && s.ID != "" { if s != nil && s.ID != "" {
stateId = s.ID
stateIdSuffix = fmt.Sprintf(" (ID: %s)", truncateId(s.ID, maxIdLen)) stateIdSuffix = fmt.Sprintf(" (ID: %s)", truncateId(s.ID, maxIdLen))
} }
@ -143,22 +141,32 @@ func (h *UiHook) PreApply(
stateIdSuffix, stateIdSuffix,
attrString))) attrString)))
// Set a timer to show an operation is still happening uiState := uiResourceState{
time.AfterFunc(periodicUiTimer, func() { h.stillApplying(id, s) }) Name: id,
ResourceId: stateId,
Op: op,
Start: time.Now().Round(time.Second),
DoneCh: make(chan struct{}),
}
h.l.Lock()
h.resources[id] = uiState
h.l.Unlock()
// Start goroutine that shows progress
go h.stillApplying(uiState)
return terraform.HookActionContinue, nil return terraform.HookActionContinue, nil
} }
func (h *UiHook) stillApplying(id string, s *terraform.InstanceState) { func (h *UiHook) stillApplying(state uiResourceState) {
// Grab the operation. We defer the lock here to avoid the "still..." for {
// message showing up after a completion message. select {
h.l.Lock() case <-state.DoneCh:
defer h.l.Unlock()
state, ok := h.resources[id]
// If the resource is out of the map it means we're done with it
if !ok {
return return
case <-time.After(periodicUiTimer):
// Timer up, show status
} }
var msg string var msg string
@ -173,21 +181,19 @@ func (h *UiHook) stillApplying(id string, s *terraform.InstanceState) {
return return
} }
var stateIdSuffix string idSuffix := ""
if s != nil && s.ID != "" { if v := state.ResourceId; v != "" {
stateIdSuffix = fmt.Sprintf("ID: %s, ", truncateId(s.ID, maxIdLen)) idSuffix = fmt.Sprintf("ID: %s, ", truncateId(v, maxIdLen))
} }
h.ui.Output(h.Colorize.Color(fmt.Sprintf( h.ui.Output(h.Colorize.Color(fmt.Sprintf(
"[reset][bold]%s: %s (%s%s elapsed)[reset]", "[reset][bold]%s: %s (%s%s elapsed)[reset]",
id, state.Name,
msg, msg,
stateIdSuffix, idSuffix,
time.Now().Round(time.Second).Sub(state.Start), time.Now().Round(time.Second).Sub(state.Start),
))) )))
}
// Reschedule
time.AfterFunc(periodicUiTimer, func() { h.stillApplying(id, s) })
} }
func (h *UiHook) PostApply( func (h *UiHook) PostApply(
@ -200,6 +206,10 @@ func (h *UiHook) PostApply(
h.l.Lock() h.l.Lock()
state := h.resources[id] state := h.resources[id]
if state.DoneCh != nil {
close(state.DoneCh)
}
delete(h.resources, id) delete(h.resources, id)
h.l.Unlock() h.l.Unlock()