github.com/orange-cloudfoundry/cli@v7.1.0+incompatible/command/v6/shared/poll_start.go (about) 1 package shared 2 3 import ( 4 "context" 5 6 "code.cloudfoundry.org/cli/actor/actionerror" 7 "code.cloudfoundry.org/cli/actor/sharedaction" 8 "code.cloudfoundry.org/cli/actor/v2action" 9 "code.cloudfoundry.org/cli/command" 10 "code.cloudfoundry.org/cli/command/translatableerror" 11 ) 12 13 func PollStart(ui command.UI, config command.Config, 14 messages <-chan sharedaction.LogMessage, 15 logErrs <-chan error, 16 appState <-chan v2action.ApplicationStateChange, 17 apiWarnings <-chan string, 18 apiErrs <-chan error, 19 stopStreaming context.CancelFunc) (apiError error) { 20 21 handleMessage := func(message sharedaction.LogMessage) { 22 if message.Staging() { 23 ui.DisplayLogMessage(message, false) 24 } 25 } 26 handleLogErr := func(logErr error) { 27 switch logErr.(type) { 28 case actionerror.LogCacheTimeoutError: 29 ui.DisplayWarning("timeout connecting to log server, no log will be shown") 30 default: 31 ui.DisplayWarning("Failed to retrieve logs from Log Cache: {{.Error}}", map[string]interface{}{ 32 "Error": logErr, 33 }) 34 } 35 } 36 for appState != nil || apiWarnings != nil || apiErrs != nil { 37 select { 38 case message, ok := <-messages: 39 if !ok { 40 messages = nil 41 continue 42 } 43 handleMessage(message) 44 45 case state, ok := <-appState: 46 if !ok { 47 appState = nil 48 continue 49 } 50 51 switch state { 52 case v2action.ApplicationStateStopping: 53 ui.DisplayNewline() 54 ui.DisplayText("Stopping app...") 55 56 case v2action.ApplicationStateStaging: 57 ui.DisplayNewline() 58 ui.DisplayText("Staging app and tracing logs...") 59 60 case v2action.ApplicationStateStarting: 61 defer func() { 62 ui.DisplayNewline() 63 ui.DisplayText("Waiting for app to start...") 64 }() 65 } 66 67 case warning, ok := <-apiWarnings: 68 if !ok { 69 apiWarnings = nil 70 continue 71 } 72 73 ui.DisplayWarning(warning) 74 75 case logErr, ok := <-logErrs: 76 if !ok { 77 logErrs = nil 78 continue 79 } 80 handleLogErr(logErr) 81 82 case e, ok := <-apiErrs: 83 if !ok { 84 apiErrs = nil 85 continue 86 } 87 switch err := e.(type) { 88 case actionerror.StagingFailedError: 89 apiError = translatableerror.StagingFailedError{Message: err.Error()} 90 case actionerror.StagingFailedNoAppDetectedError: 91 apiError = translatableerror.StagingFailedNoAppDetectedError{BinaryName: config.BinaryName(), Message: err.Error()} 92 case actionerror.StagingTimeoutError: 93 apiError = translatableerror.StagingTimeoutError{AppName: err.AppName, Timeout: err.Timeout} 94 case actionerror.ApplicationInstanceCrashedError: 95 apiError = translatableerror.ApplicationUnableToStartError{AppName: err.Name, BinaryName: config.BinaryName()} 96 case actionerror.ApplicationInstanceFlappingError: 97 apiError = translatableerror.ApplicationUnableToStartError{AppName: err.Name, BinaryName: config.BinaryName()} 98 case actionerror.StartupTimeoutError: 99 apiError = translatableerror.StartupTimeoutError{AppName: err.Name, BinaryName: config.BinaryName()} 100 default: 101 apiError = err 102 } 103 // if an api error occurred, exit immediately 104 stopStreaming() 105 return apiError 106 } 107 } 108 stopStreaming() 109 110 // Consume any pending streamed messages 111 for messages != nil || logErrs != nil { 112 select { 113 case message, ok := <-messages: 114 if !ok { 115 messages = nil 116 continue 117 } 118 handleMessage(message) 119 120 case logErr, ok := <-logErrs: 121 if !ok { 122 logErrs = nil 123 continue 124 } 125 handleLogErr(logErr) 126 } 127 } 128 return nil 129 }