Go Http Handler is restarting itself during the execution of a command (cmd.Command)

124

Solution 1

It's a trade-off between the cost of storage vs the cost of losing data.

Postgres will create a new WAL file when it reaches 16 MB. If that takes a week, then you might lose that 16 MB of data if bad things happen before the new data reaches that size.

If you set archive_timeout to an hour, then you get a new 16 MB file every hour, even if there isn't 16 MB of actual data.

It's faster to restore a recent base backup and fewer/smaller WAL backups too.

How quickly do you need to recover from a catastrophic loss?

Storage is pretty cheap these days, and people's time is expensive. I would go with at least a weekly base backup and hourly or daily incremental backups.

Solution 2

There's a couple of things of note:

  • capturing stdout and stderr seems brittle (error handling from goroutine will not propagate properly)
  • long running executable may cause request timeout issues

to capture stdout and stderr - I'd suggest using something like exec.Cmd.CombinedOutput e.g.

cmd := exec.CommandContext(ctx, "flutter", "build", "appbundle") // see below for ctx details

var sout, serr bytes.Buffer
c.Stdout = &sout
c.Stderr = &serr
err := c.Run()
if err != nil { /* ... */ }

outBody, errBody := string(sout.Bytes()), string(serr.Bytes())

so no need for tricky wait-groups or complex error handling between goroutines.


You need to handle the case where web-requests may take too long. If a request is canceled (by the client or the server) - you need a mechanism in place to cancel the request's sub-tasks (e.g. you externally executed process)

When running any webservice always ensure to leverage context.Context for the lifetime of a request - especially when running any potentially blocking operations (as you are with exec.Command).

So first, from your handler, grab the request's context.Context, and pass this along to any potentially blocking calls:

func (h *HttpServer) GenerateMobileApp(w http.ResponseWriter, r *http.Request) {
    ...
    ctx := r.Context()  // context.Context for the lifetime of the request

    ...
    go func() {
        apkGeneratedPath, err := h.mobileAPP.GenerateAPK(ctx, project.Id) // <- add ctx
    }

}

and update your APK generator signature like so:

func (app *MobileAPP) GenerateAPK(ctx context.Context, projectID string) (string, error)

and to use ctx when executing an external tool:

//cmd := exec.Command("flutter", "build", "appbundle")
cmd := exec.CommandContext(ctx, "flutter", "build", "appbundle")

with this in place, if the web request is canceled (times out - based on web server settings; or the client disconnects) the process will be terminated. You can even have special clean-up logic in place for this occurrence, by checking the error from exec.CommandContext for either context.Canceled (client disconnected) or context.DeadlineExceeded (request timed-out).

Share:
124

Related videos on Youtube

Mael Fosso
Author by

Mael Fosso

Updated on January 03, 2023

Comments

  • Mael Fosso
    Mael Fosso over 1 year

    Please, I have an issue on a golang web application. I don’t understand why is happening

    Here is the code of the http handler

    [Updated from the comment of @colm.anseo about using context]

    func (h *HttpServer) GenerateMobileApp(w http.ResponseWriter, r *http.Request) {
        ctx := r.Context()
    
        vars := mux.Vars(r)
        pid := vars["id"]
    
        // Check if the project exists : gRPC - to Project micro-services - ask to project-api msvc
        // var project *models.Project
        // if project, err := h.projectClient.IsProjectExists() isProjectExists(pid); err != nil {
        var project *protos.ProjectReply
        idRequest := &protos.IDRequest{
            Id: pid,
        }
        project, err := h.projectClient.IsProjectExists(r.Context(), idRequest)
        if err != nil {
            h.JSON(w, http.StatusInternalServerError, fmt.Errorf("error when checking project existance"))
            return
        }
        if project == nil {
            h.JSON(w, http.StatusBadRequest, fmt.Errorf("project does not exists"))
            return
        }
        log.Println("Grpc downloaded Project : \n\t", project)
    
        // Save locally the downloaded project
        if err := h.store.SaveDownloadedProject(project); err != nil {
            h.JSON(w, http.StatusBadRequest, fmt.Errorf("error when saving the downloaded project"))
            return
        }
    
        // Download the repository
        if err := h.mobileAPP.CloneBoilerplate(project.Id); err != nil {
            h.JSON(w, http.StatusBadRequest, fmt.Errorf("error when cloning boilerplate"))
            return
        }
        log.Println("Project successfully clone ", h.mobileAPP)
    
        if err := h.mobileAPP.Update(project); err != nil {
            h.JSON(w, http.StatusBadRequest, fmt.Errorf("error when updating boilerplate"))
            return
        }
        log.Println("TODO - Update the project not done yet")
    
     
        apkGenerationDone := make(chan bool)
        go func() {
            apkGeneratedPath, err := h.mobileAPP.GenerateAPK(ctx, project.Id)
            if err != nil {
                log.Println("error when generation APK")
                h.JSON(w, http.StatusBadRequest, fmt.Errorf("error when generating APK"))
    
                apkGenerationDone <- false
                return
            }
            log.Println("APK Generated correctly: ", apkGeneratedPath)
            apkGenerationDone <- true
        }()
    
        select {
        case <-ctx.Done():
            log.Println("[GENERATE_MOBILE_APP] context done, process timeout: ", ctx.Err())
            h.JSON(w, http.StatusRequestTimeout, "process timeout")
        // case <-r.Context().
        case <-apkGenerationDone:
            log.Println("[GENERATE_MOBILE_APP] successful")
            h.JSON(w, http.StatusCreated, "link of the play store app")
        }
    
        // Save in the DB the APK generated
    
        h.JSON(w, http.StatusCreated, "link of the play store app")
    }
    

    Here is the code of h.mobileAPP.GenerateAPK(project.id)

    func (app *MobileAPP) GenerateAPK(ctx context.Context, projectID string) (string, error) {
        log.Println("[GENERATED_APK] Start : ", projectID)
    
        generatedAppFolder := fmt.Sprint("app-", projectID)
        generatedAppFolderPath := filepath.Join(CLONED_APP_FOLDER, generatedAppFolder)
        os.Chdir(generatedAppFolderPath) // (filepath.Join(CLONED_APP_FOLDER, projectID))
        log.Println("[GENERATED_APK] Changed Directory to : ", generatedAppFolderPath)
    
        log.Println("[GENERATED_APK] Running : flutter build appbundle")
    
        cmd := exec.CommandContext(ctx, "flutter", "build", "appbundle")
    
        stdout, _ := cmd.StdoutPipe()
        stderr, _ := cmd.StderrPipe()
    
        cmd.Start()
    
        var wg sync.WaitGroup
        wg.Add(1)
        go func() {
            oneByteStderr := make([]byte, 100)
            for {
                _, err := stderr.Read(oneByteStderr)
                if err != nil {
                    log.Println("[GENERATED_APK][STDErr] stdout.Read error : ", err.Error())
                    break
                }
                r := bufio.NewReader(stderr)
                line, _, _ := r.ReadLine()
                log.Println("[GENERATED_APK][STDErr] r.ReadLine() ", string(line))
            }
            wg.Done()
        }()
    
        // num := 1
        oneByte := make([]byte, 100)
        for {
            _, err := stdout.Read(oneByte)
            if err != nil {
                log.Println("[GENERATED_APK] stdout.Read error : ", err.Error())
                break
            }
            r := bufio.NewReader(stdout)
            line, _, _ := r.ReadLine()
            log.Println("[GENERATED_APK] r.ReadLine() ", string(line))
        }
        wg.Wait()
        err := cmd.Wait()
        if err != nil {
            log.Fatalf("[GENERATED_APK] cmd.Run() failed with %s\n", err)
        }
    
        return "", nil
    
    }
    

    You can notice that I am running a command flutter build appbundle at cmd := exec.CommandContext("flutter", "build", "appbundle")

    The issue I have is that that command doesn’t finish. During it’s execution, after a few minute the http handler restart from the beginning. Not the GeneratedAPK method but the whole handler func (h *HttpServer) GenerateMobileApp restart from the beginning thus causing many flutter build appbundle processes . And it stopped when the first one is done. And it makes the http handler too long.

    [Added for a better understanding]

    Here is the full log of the corresponding POD

    2022/01/19 08:10:17 Guitou mobile generator
    2022/01/19 08:10:17 NewHttpServer()
    2022/01/19 08:10:17 Connecting to gRPC Project
    2022/01/19 08:10:17 Successful connection to gRPC Project Server
    
    ********* STARTING HERE *****************
    2022/01/19 08:21:27 Grpc downloaded Project : 
         id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:21:27 Save Download Project : 
        id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:21:27 [CloneBoilerplate] Start
    2022/01/19 08:21:27 Already clone: [/home/guitou/app-generated/conf-61a867371b1331002c7595cc] 
     %!s(<nil>)
    2022/01/19 08:21:27 Last clone folder removed
    2022/01/19 08:21:27 [CloneBoilerplate] *** Let's clone it :  https://gitlab.com/guitou-app/mobile-templates.git
    
    Enumerating objects: 25, done.
    Counting objects:   4% (1/25)
    Counting objects:   8% (2/25)
    Counting objects:  12% (3/25)
    Counting objects:  16% (4/25)
    Counting objects:  20% (5/25)
    Counting objects:  24% (6/25)
    Counting objects:  28% (7/25)
    Counting objects:  32% (8/25)
    Counting objects:  36% (9/25)
    Counting objects:  40% (10/25)
    Counting objects:  44% (11/25)
    Counting objects:  48% (12/25)
    Counting objects:  52% (13/25)
    Counting objects:  56% (14/25)
    Counting objects:  60% (15/25)
    Counting objects:  64% (16/25)
    Counting objects:  68% (17/25)
    Counting objects:  72% (18/25)
    Counting objects:  76% (19/25)
    Counting objects:  80% (20/25)
    Counting objects:  84% (21/25)
    Counting objects:  88% (22/25)
    Counting objects:  92% (23/25)
    Counting objects:  96% (24/25)
    Counting objects: 100% (25/25)
    Counting objects: 100% (25/25), done.
    Compressing objects:   4% (1/24)
    Compressing objects:   8% (2/24)
    Compressing objects:  12% (3/24)
    Compressing objects:  16% (4/24)
    Compressing objects:  20% (5/24)
    Compressing objects:  25% (6/24)
    Compressing objects:  29% (7/24)
    Compressing objects:  33% (8/24)
    Compressing objects:  37% (9/24)
    Compressing objects:  41% (10/24)
    Compressing objects:  45% (11/24)
    Compressing objects:  50% (12/24)
    Compressing objects:  54% (13/24)
    Compressing objects:  58% (14/24)
    Compressing objects:  62% (15/24)
    Compressing objects:  66% (16/24)
    Compressing objects:  70% (17/24)
    Compressing objects:  75% (18/24)
    Compressing objects:  79% (19/24)
    Compressing objects:  83% (20/24)
    Compressing objects:  87% (21/24)
    Compressing objects:  91% (22/24)
    Compressing objects:  95% (23/24)
    Compressing objects: 100% (24/24)
    Compressing objects: 100% (24/24), done.
    Total 25 (delta 5), reused 0 (delta 0), pack-reused 0
    2022/01/19 08:21:30 [CloneBoilerplate] Finish cloning
    2022/01/19 08:21:30 [CloneBoilerplate] End
    2022/01/19 08:21:30 &{0xc0003c2930}
    2022/01/19 08:21:30 Project successfully clone  &{0xc0003c2930}
    2022/01/19 08:21:30 [UPDATE] Project Conf Path :  /home/guitou/app-generated/conf-61a867371b1331002c7595cc
    2022/01/19 08:21:30 [Update] Start
    2022/01/19 08:21:30 [Update] WalkMatch :  [files/AndroidManifest.xml.tmpl files/Appfile.tmpl files/MainActivity.kt.tmpl files/build.gradle.tmpl files/data_list_page.dart.tmpl files/init.dart.tmpl files/pubspec.yaml.tmpl]
    2022/01/19 08:21:30 [Update] Updating files started
    2022/01/19 08:21:30 
    
    ************* pubspec.yaml.tmpl
    2022/01/19 08:21:30 
    
    ************* MainActivity.kt.tmpl
    2022/01/19 08:21:30 
    
    ************* data_list_page.dart.tmpl
    2022/01/19 08:21:30 
    
    ************* AndroidManifest.xml.tmpl
    2022/01/19 08:21:30 
    
    ************* init.dart.tmpl
    2022/01/19 08:21:30 
    
    ************* Appfile.tmpl
    2022/01/19 08:21:30 
    
    ************* build.gradle.tmpl
    2022/01/19 08:21:30 Execute Project  id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:21:30  [email protected]
    2022/01/19 08:21:30 Execute Project  id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:21:30  [email protected]
    2022/01/19 08:21:30 Execute Project  id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:21:30  [email protected]
    2022/01/19 08:21:30 Execute Project  id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:21:30  [email protected]
    2022/01/19 08:21:30 Execute Project  id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:21:30  [email protected]
    2022/01/19 08:21:30 Execute Project  id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:21:30  [email protected]
    2022/01/19 08:21:30 Execute Project  id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:21:30  [email protected]
    2022/01/19 08:21:30 [Update] Updating files end
    2022/01/19 08:21:30 [UPDATE] Deep copy of the boilerplate folder : app-{projectID}
    2022/01/19 08:22:14 [UPDATE] Deep copy ends.
    2022/01/19 08:22:14 [UPDATE] Load config.yaml
    2022/01/19 08:22:14 [UPDATE] Config Loaded  {[]}
    2022/01/19 08:22:14 [UPDATE] Moved the transformed files into the app-{projectID}
    2022/01/19 08:22:14 TODO - Update the project not done yet
    2022/01/19 08:22:14 [GENERATED_APK] Start :  61a867371b1331002c7595cc
    2022/01/19 08:22:14 [GENERATED_APK] Changed Directory to :  /home/guitou/app-generated/app-61a867371b1331002c7595cc
    2022/01/19 08:22:14 [GENERATED_APK] Running : flutter build appbundle
    10.1.1.133 - - [19/Jan/2022:08:21:27 +0000] "GET /61a867371b1331002c7595cc HTTP/1.1" 408 18
    2022/01/19 08:22:27 [GENERATE_MOBILE_APP] context done, process timeout:  context canceled
    
    ************* RESTARTING HERE ***********************
    2022/01/19 08:22:27 Grpc downloaded Project : 
         id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:22:27 Save Download Project : 
        id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:22:27 [CloneBoilerplate] Start
    2022/01/19 08:22:27 Already clone: [/home/guitou/app-generated/conf-61a867371b1331002c7595cc] 
     %!s(<nil>)
    2022/01/19 08:22:27 Last clone folder removed
    2022/01/19 08:22:27 [CloneBoilerplate] *** Let's clone it :  https://gitlab.com/guitou-app/mobile-templates.git
    
    Enumerating objects: 25, done.
    Counting objects:   4% (1/25)
    Counting objects:   8% (2/25)
    Counting objects:  12% (3/25)
    Counting objects:  16% (4/25)
    Counting objects:  20% (5/25)
    Counting objects:  24% (6/25)
    Counting objects:  28% (7/25)
    Counting objects:  32% (8/25)
    Counting objects:  36% (9/25)
    Counting objects:  40% (10/25)
    Counting objects:  44% (11/25)
    Counting objects:  48% (12/25)
    Counting objects:  52% (13/25)
    Counting objects:  56% (14/25)
    Counting objects:  60% (15/25)
    Counting objects:  64% (16/25)
    Counting objects:  68% (17/25)
    Counting objects:  72% (18/25)
    Counting objects:  76% (19/25)
    Counting objects:  80% (20/25)
    Counting objects:  84% (21/25)
    Counting objects:  88% (22/25)
    Counting objects:  92% (23/25)
    Counting objects:  96% (24/25)
    Counting objects: 100% (25/25)
    Counting objects: 100% (25/25), done.
    Compressing objects:   4% (1/24)
    Compressing objects:   8% (2/24)
    Compressing objects:  12% (3/24)
    Compressing objects:  16% (4/24)
    Compressing objects:  20% (5/24)
    Compressing objects:  25% (6/24)
    Compressing objects:  29% (7/24)
    Compressing objects:  33% (8/24)
    Compressing objects:  37% (9/24)
    Compressing objects:  41% (10/24)
    Compressing objects:  45% (11/24)
    Compressing objects:  50% (12/24)
    Compressing objects:  54% (13/24)
    Compressing objects:  58% (14/24)
    Compressing objects:  62% (15/24)
    Compressing objects:  66% (16/24)
    Compressing objects:  70% (17/24)
    Compressing objects:  75% (18/24)
    Compressing objects:  79% (19/24)
    Compressing objects:  83% (20/24)
    Compressing objects:  87% (21/24)
    Compressing objects:  91% (22/24)
    Compressing objects:  95% (23/24)
    Compressing objects: 100% (24/24)
    Compressing objects: 100% (24/24), done.
    Total 25 (delta 5), reused 0 (delta 0), pack-reused 0
    2022/01/19 08:22:29 [CloneBoilerplate] Finish cloning
    2022/01/19 08:22:29 [CloneBoilerplate] End
    2022/01/19 08:22:29 &{0xc000596690}
    2022/01/19 08:22:29 Project successfully clone  &{0xc000596690}
    2022/01/19 08:22:29 [UPDATE] Project Conf Path :  /home/guitou/app-generated/conf-61a867371b1331002c7595cc
    2022/01/19 08:22:29 [Update] Start
    2022/01/19 08:22:29 [Update] WalkMatch :  [files/AndroidManifest.xml.tmpl files/Appfile.tmpl files/MainActivity.kt.tmpl files/build.gradle.tmpl files/data_list_page.dart.tmpl files/init.dart.tmpl files/pubspec.yaml.tmpl]
    2022/01/19 08:22:29 [Update] Updating files started
    2022/01/19 08:22:29 
    
    ************* MainActivity.kt.tmpl
    2022/01/19 08:22:29 
    
    ************* build.gradle.tmpl
    2022/01/19 08:22:29 
    
    ************* AndroidManifest.xml.tmpl
    2022/01/19 08:22:29 
    
    ************* Appfile.tmpl
    2022/01/19 08:22:29 
    
    ************* data_list_page.dart.tmpl
    2022/01/19 08:22:29 
    
    ************* init.dart.tmpl
    2022/01/19 08:22:29 
    
    ************* pubspec.yaml.tmpl
    2022/01/19 08:22:29 Execute Project  id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:22:29  [email protected]
    2022/01/19 08:22:29 Execute Project  id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:22:29  [email protected]
    2022/01/19 08:22:29 Execute Project  id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:22:29  [email protected]
    2022/01/19 08:22:29 Execute Project  id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:22:29  [email protected]
    2022/01/19 08:22:29 Execute Project  id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:22:29  [email protected]
    2022/01/19 08:22:29 Execute Project  id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:22:29  [email protected]
    2022/01/19 08:22:29 Execute Project  id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:22:29  [email protected]
    2022/01/19 08:22:29 [Update] Updating files end
    2022/01/19 08:22:29 [UPDATE] Deep copy of the boilerplate folder : app-{projectID}
    2022/01/19 08:22:36 [GENERATED_APK] r.ReadLine()  ��═══════════════════════════════════════════╗
    2022/01/19 08:22:44 [GENERATED_APK] r.ReadLine()      5.3s
    2022/01/19 08:22:45 [GENERATED_APK] r.ReadLine()   1,434ms
    2022/01/19 08:22:48 [GENERATED_APK] r.ReadLine()   2,229ms
    2022/01/19 08:22:52 [GENERATED_APK] r.ReadLine()      4.0s
    2022/01/19 08:22:58 [GENERATED_APK] r.ReadLine()      6.5s
    2022/01/19 08:23:00 [GENERATED_APK] r.ReadLine()   1,386ms
    2022/01/19 08:23:06 [UPDATE] Deep copy ends.
    2022/01/19 08:23:06 [UPDATE] Load config.yaml
    2022/01/19 08:23:06 [UPDATE] Config Loaded  {[]}
    2022/01/19 08:23:06 [UPDATE] Moved the transformed files into the app-{projectID}
    2022/01/19 08:23:06 TODO - Update the project not done yet
    2022/01/19 08:23:06 [GENERATED_APK] Start :  61a867371b1331002c7595cc
    2022/01/19 08:23:06 [GENERATED_APK] Changed Directory to :  /home/guitou/app-generated/app-61a867371b1331002c7595cc
    2022/01/19 08:23:06 [GENERATED_APK] Running : flutter build appbundle
    2022/01/19 08:23:27 [GENERATE_MOBILE_APP] context done, process timeout:  context canceled
    10.1.1.133 - - [19/Jan/2022:08:22:27 +0000] "GET /61a867371b1331002c7595cc HTTP/1.1" 408 18
    
    ************* RESTARTING HERE ***********************
    2022/01/19 08:23:27 Grpc downloaded Project : 
         id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:23:27 Save Download Project : 
        id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:23:27 [CloneBoilerplate] Start
    2022/01/19 08:23:27 Already clone: [/home/guitou/app-generated/conf-61a867371b1331002c7595cc] 
     %!s(<nil>)
    2022/01/19 08:23:27 Last clone folder removed
    2022/01/19 08:23:27 [CloneBoilerplate] *** Let's clone it :  https://gitlab.com/guitou-app/mobile-templates.git
    
    Enumerating objects: 25, done.
    Counting objects:   4% (1/25)
    Counting objects:   8% (2/25)
    Counting objects:  12% (3/25)
    Counting objects:  16% (4/25)
    Counting objects:  20% (5/25)
    Counting objects:  24% (6/25)
    Counting objects:  28% (7/25)
    Counting objects:  32% (8/25)
    Counting objects:  36% (9/25)
    Counting objects:  40% (10/25)
    Counting objects:  44% (11/25)
    Counting objects:  48% (12/25)
    Counting objects:  52% (13/25)
    Counting objects:  56% (14/25)
    Counting objects:  60% (15/25)
    Counting objects:  64% (16/25)
    Counting objects:  68% (17/25)
    Counting objects:  72% (18/25)
    Counting objects:  76% (19/25)
    Counting objects:  80% (20/25)
    Counting objects:  84% (21/25)
    Counting objects:  88% (22/25)
    Counting objects:  92% (23/25)
    Counting objects:  96% (24/25)
    Counting objects: 100% (25/25)
    Counting objects: 100% (25/25), done.
    Compressing objects:   4% (1/24)
    Compressing objects:   8% (2/24)
    Compressing objects:  12% (3/24)
    Compressing objects:  16% (4/24)
    Compressing objects:  20% (5/24)
    Compressing objects:  25% (6/24)
    Compressing objects:  29% (7/24)
    Compressing objects:  33% (8/24)
    Compressing objects:  37% (9/24)
    Compressing objects:  41% (10/24)
    Compressing objects:  45% (11/24)
    Compressing objects:  50% (12/24)
    Compressing objects:  54% (13/24)
    Compressing objects:  58% (14/24)
    Compressing objects:  62% (15/24)
    Compressing objects:  66% (16/24)
    Compressing objects:  70% (17/24)
    Compressing objects:  75% (18/24)
    Compressing objects:  79% (19/24)
    Compressing objects:  83% (20/24)
    Compressing objects:  87% (21/24)
    Compressing objects:  91% (22/24)
    Compressing objects:  95% (23/24)
    Compressing objects: 100% (24/24)
    Compressing objects: 100% (24/24), done.
    Total 25 (delta 5), reused 0 (delta 0), pack-reused 0
    2022/01/19 08:23:30 [CloneBoilerplate] Finish cloning
    2022/01/19 08:23:30 [CloneBoilerplate] End
    2022/01/19 08:23:30 &{0xc0007928a0}
    2022/01/19 08:23:30 Project successfully clone  &{0xc0007928a0}
    2022/01/19 08:23:30 [UPDATE] Project Conf Path :  /home/guitou/app-generated/conf-61a867371b1331002c7595cc
    2022/01/19 08:23:30 [Update] Start
    2022/01/19 08:23:30 [Update] WalkMatch :  [files/AndroidManifest.xml.tmpl files/Appfile.tmpl files/MainActivity.kt.tmpl files/build.gradle.tmpl files/data_list_page.dart.tmpl files/init.dart.tmpl files/pubspec.yaml.tmpl]
    2022/01/19 08:23:30 [Update] Updating files started
    2022/01/19 08:23:30 
    
    ************* Appfile.tmpl
    2022/01/19 08:23:30 
    
    ************* build.gradle.tmpl
    2022/01/19 08:23:30 
    
    ************* AndroidManifest.xml.tmpl
    2022/01/19 08:23:30 
    
    ************* data_list_page.dart.tmpl
    2022/01/19 08:23:30 
    
    ************* MainActivity.kt.tmpl
    2022/01/19 08:23:30 
    
    ************* pubspec.yaml.tmpl
    2022/01/19 08:23:30 
    
    ************* init.dart.tmpl
    2022/01/19 08:23:30 Execute Project  id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:23:30  [email protected]
    2022/01/19 08:23:30 Execute Project  id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:23:30  [email protected]
    2022/01/19 08:23:30 Execute Project  id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:23:30  [email protected]
    2022/01/19 08:23:30 Execute Project  id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:23:30  [email protected]
    2022/01/19 08:23:30 Execute Project  id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:23:30  [email protected]
    2022/01/19 08:23:30 Execute Project  id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:23:30  [email protected]
    2022/01/19 08:23:30 Execute Project  id:"61a867371b1331002c7595cc"  title:"testing stufff"  description:"Go there"  author:{email:"[email protected]"}  xorms:{id:"61a8673a1b1331002c7595d0"  title:"Xorm 1"  level:"primary"}
    2022/01/19 08:23:30  [email protected]
    2022/01/19 08:23:30 [Update] Updating files end
    2022/01/19 08:23:30 [UPDATE] Deep copy of the boilerplate folder : app-{projectID}
    2022/01/19 08:23:36 [GENERATED_APK] r.ReadLine()     35.9s
    2022/01/19 08:23:37 [GENERATED_APK] r.ReadLine()  For more information see https://dart.dev/null-safety/unsound-null-safety
    2022/01/19 08:23:39 [GENERATED_APK] r.ReadLine()     31.6s
    2022/01/19 08:23:40 [GENERATED_APK] r.ReadLine()  Building without sound null safety
    2022/01/19 08:24:12 [UPDATE] Deep copy ends.
    2022/01/19 08:24:12 [UPDATE] Load config.yaml
    2022/01/19 08:24:12 [UPDATE] Config Loaded  {[]}
    2022/01/19 08:24:12 [UPDATE] Moved the transformed files into the app-{projectID}
    2022/01/19 08:24:12 TODO - Update the project not done yet
    2022/01/19 08:24:12 [GENERATED_APK] Start :  61a867371b1331002c7595cc
    2022/01/19 08:24:12 [GENERATED_APK] Changed Directory to :  /home/guitou/app-generated/app-61a867371b1331002c7595cc
    2022/01/19 08:24:12 [GENERATED_APK] Running : flutter build appbundle
    2022/01/19 08:24:22 [GENERATED_APK] r.ReadLine()      7.7s
    2022/01/19 08:24:22 [GENERATED_APK] r.ReadLine()  Building without sound null safety
    2022/01/19 08:24:22 [GENERATED_APK] r.ReadLine()  
    2022/01/19 08:24:27 [GENERATE_MOBILE_APP] context done, process timeout:  context canceled
    10.1.1.133 - - [19/Jan/2022:08:23:27 +0000] "GET /61a867371b1331002c7595cc HTTP/1.1" 408 18
    
    ************* RESTARTING HERE ***********************
    2022/01/19 08:24:31 [GENERATED_APK] r.ReadLine()  Running Gradle task 'bundleRelease'...                          
    2022/01/19 08:24:31 [GENERATED_APK] r.ReadLine()  License for package Android SDK Platform 29 accepted.
    2022/01/19 08:24:31 [GENERATED_APK] r.ReadLine()  
    2022/01/19 08:24:31 [GENERATED_APK] r.ReadLine()  License for package Android SDK Platform 29 accepted.
    2022/01/19 08:24:51 [GENERATED_APK] r.ReadLine()  
    2022/01/19 08:24:51 [GENERATED_APK] r.ReadLine()  Preparing "Install Android SDK Platform 29 (revision: 5)".
    2022/01/19 08:25:51 [GENERATED_APK] r.ReadLine()  "Install Android SDK Platform 29 (revision: 5)" ready.
    2022/01/19 08:25:51 [GENERATED_APK] r.ReadLine()  "Install Android SDK Platform 29 (revision: 5)" complete.
    2022/01/19 08:25:54 [GENERATED_APK][STDErr] r.ReadLine()  FAILURE: Build failed with an exception.
    2022/01/19 08:25:54 [GENERATED_APK][STDErr] r.ReadLine()  * What went wrong:
    2022/01/19 08:25:54 [GENERATED_APK][STDErr] r.ReadLine()  > Failed to create parent directory '/Users' when creating directory '/Users/maelfosso/Documents/Guitou/GitLab/mobile/mobile-app-boilerplate/build/app/intermediates/flutter/release/arm64-v8a'
    2022/01/19 08:25:54 [GENERATED_APK][STDErr] r.ReadLine()  * Try:
    2022/01/19 08:25:54 [GENERATED_APK][STDErr] r.ReadLine()  og output. Run with --scan to get full insights.
    2022/01/19 08:25:54 [GENERATED_APK][STDErr] r.ReadLine()  
    2022/01/19 08:25:54 [GENERATED_APK] r.ReadLine()  Warning: Failed to download package!
    2022/01/19 08:25:55 [GENERATED_APK][STDErr] r.ReadLine()  FAILURE: Build failed with an exception.
    2022/01/19 08:25:55 [GENERATED_APK][STDErr] r.ReadLine()  * What went wrong:
    2022/01/19 08:25:55 [GENERATED_APK][STDErr] r.ReadLine()  > Failed to install the following SDK components:
    2022/01/19 08:25:55 [GENERATED_APK][STDErr] r.ReadLine()    Install the missing components using the SDK manager in Android Studio.
    2022/01/19 08:25:55 [GENERATED_APK][STDErr] r.ReadLine()  
    2022/01/19 08:25:55 [GENERATED_APK][STDErr] r.ReadLine()  Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
    2022/01/19 08:25:55 [GENERATED_APK][STDErr] r.ReadLine()  * Get more help at https://help.gradle.org
    2022/01/19 08:25:55 [GENERATED_APK][STDErr] r.ReadLine()  BUILD FAILED in 2m 14s
    2022/01/19 08:25:55 [GENERATED_APK] r.ReadLine()  Running Gradle task 'bundleRelease'...                            137.7s
    2022/01/19 08:25:55 [GENERATED_APK][STDErr] r.ReadLine()  Gradle task bundleRelease failed with exit code 1
    2022/01/19 08:25:55 [GENERATED_APK] stdout.Read error :  EOF
    2022/01/19 08:25:55 [GENERATED_APK][STDErr] stdout.Read error :  EOF
    2022/01/19 08:25:55 [GENERATED_APK] cmd.Run() failed with signal: killed
    

    Take a look at the section ********* STARTING HERE ***************** and ************* RESTARTING HERE *********************** to notice that the handler it's restarting.

    You can notice also that the even with the timeout the command exec.CommandContext("flutter", "build", "appbundle") is still running even after the context timeout.

    Why such a behavior from exec.CommandContext? How to stop the http handler after the context timeout ?

    • colm.anseo
      colm.anseo over 2 years
      how you're capturing stdout and stderr seems very brittle. I've updated my answer below with some suggestions there.
    • Mael Fosso
      Mael Fosso over 2 years
      @colm.anseo From what I read about CombinedOutput it returns the output after the command has been processed right? That's not what I would like to do. I would like to have the output in real-time because that output will be sent to the user in real-time, I mean line by line, as it is generated.
  • Mael Fosso
    Mael Fosso over 2 years
    thank you for your suggestion.
  • Mael Fosso
    Mael Fosso over 2 years
    do you think that if the times out can cause the handler to restart again ?
  • Mael Fosso
    Mael Fosso over 2 years
    sorry but the app is crashing and I don't understand the output, and the pod is no longer receiving the request. what is it supposed to show me? I would like to show you the output but I don't know how to do it in a comment
  • Mael Fosso
    Mael Fosso over 2 years
    I tried the CombinedOuput but with the same output I updated the problem with the output
  • Mael Fosso
    Mael Fosso over 2 years
    added log output
  • Mael Fosso
    Mael Fosso over 2 years
    Sorry but with exec.CommandContext the command is not stopped when context timeout occurs