<p>Please, I have an issue on a golang web application.
I don’t understand why is happening</p>
<p>Here is the code of the http handler</p>
<p>[Updated from the comment of @colm.anseo about using context]</p>
<pre class="lang-golang prettyprint-override"><code>func (h *HttpServer) GenerateMobileApp(w http.ResponseWriter, r *http.Request) {
    ctx := r.Context()

    vars := mux.Vars(r)
    pid := vars[&quot;id&quot;]

    // 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 := &amp;protos.IDRequest{
        Id: pid,
    }
    project, err := h.projectClient.IsProjectExists(r.Context(), idRequest)
    if err != nil {
        h.JSON(w, http.StatusInternalServerError, fmt.Errorf(&quot;error when checking project existance&quot;))
        return
    }
    if project == nil {
        h.JSON(w, http.StatusBadRequest, fmt.Errorf(&quot;project does not exists&quot;))
        return
    }
    log.Println(&quot;Grpc downloaded Project : \n\t&quot;, project)

    // Save locally the downloaded project
    if err := h.store.SaveDownloadedProject(project); err != nil {
        h.JSON(w, http.StatusBadRequest, fmt.Errorf(&quot;error when saving the downloaded project&quot;))
        return
    }

    // Download the repository
    if err := h.mobileAPP.CloneBoilerplate(project.Id); err != nil {
        h.JSON(w, http.StatusBadRequest, fmt.Errorf(&quot;error when cloning boilerplate&quot;))
        return
    }
    log.Println(&quot;Project successfully clone &quot;, h.mobileAPP)

    if err := h.mobileAPP.Update(project); err != nil {
        h.JSON(w, http.StatusBadRequest, fmt.Errorf(&quot;error when updating boilerplate&quot;))
        return
    }
    log.Println(&quot;TODO - Update the project not done yet&quot;)

 
    apkGenerationDone := make(chan bool)
    go func() {
        apkGeneratedPath, err := h.mobileAPP.GenerateAPK(ctx, project.Id)
        if err != nil {
            log.Println(&quot;error when generation APK&quot;)
            h.JSON(w, http.StatusBadRequest, fmt.Errorf(&quot;error when generating APK&quot;))

            apkGenerationDone &lt;- false
            return
        }
        log.Println(&quot;APK Generated correctly: &quot;, apkGeneratedPath)
        apkGenerationDone &lt;- true
    }()

    select {
    case &lt;-ctx.Done():
        log.Println(&quot;[GENERATE_MOBILE_APP] context done, process timeout: &quot;, ctx.Err())
        h.JSON(w, http.StatusRequestTimeout, &quot;process timeout&quot;)
    // case &lt;-r.Context().
    case &lt;-apkGenerationDone:
        log.Println(&quot;[GENERATE_MOBILE_APP] successful&quot;)
        h.JSON(w, http.StatusCreated, &quot;link of the play store app&quot;)
    }

    // Save in the DB the APK generated

    h.JSON(w, http.StatusCreated, &quot;link of the play store app&quot;)
}
</code></pre>
<p>Here is the code of <code>h.mobileAPP.GenerateAPK(project.id)</code></p>
<pre class="lang-golang prettyprint-override"><code>func (app *MobileAPP) GenerateAPK(ctx context.Context, projectID string) (string, error) {
    log.Println(&quot;[GENERATED_APK] Start : &quot;, projectID)

    generatedAppFolder := fmt.Sprint(&quot;app-&quot;, projectID)
    generatedAppFolderPath := filepath.Join(CLONED_APP_FOLDER, generatedAppFolder)
    os.Chdir(generatedAppFolderPath) // (filepath.Join(CLONED_APP_FOLDER, projectID))
    log.Println(&quot;[GENERATED_APK] Changed Directory to : &quot;, generatedAppFolderPath)

    log.Println(&quot;[GENERATED_APK] Running : flutter build appbundle&quot;)

    cmd := exec.CommandContext(ctx, &quot;flutter&quot;, &quot;build&quot;, &quot;appbundle&quot;)

    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(&quot;[GENERATED_APK][STDErr] stdout.Read error : &quot;, err.Error())
                break
            }
            r := bufio.NewReader(stderr)
            line, _, _ := r.ReadLine()
            log.Println(&quot;[GENERATED_APK][STDErr] r.ReadLine() &quot;, string(line))
        }
        wg.Done()
    }()

    // num := 1
    oneByte := make([]byte, 100)
    for {
        _, err := stdout.Read(oneByte)
        if err != nil {
            log.Println(&quot;[GENERATED_APK] stdout.Read error : &quot;, err.Error())
            break
        }
        r := bufio.NewReader(stdout)
        line, _, _ := r.ReadLine()
        log.Println(&quot;[GENERATED_APK] r.ReadLine() &quot;, string(line))
    }
    wg.Wait()
    err := cmd.Wait()
    if err != nil {
        log.Fatalf(&quot;[GENERATED_APK] cmd.Run() failed with %s\n&quot;, err)
    }

    return &quot;&quot;, nil

}
</code></pre>
<p>You can notice that I am running a command flutter build appbundle  at <code>cmd := exec.CommandContext(&quot;flutter&quot;, &quot;build&quot;, &quot;appbundle&quot;)</code></p>
<p>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 <code>GeneratedAPK</code> method but the whole handler <code>func (h *HttpServer) GenerateMobileApp</code> 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.</p>
<p>[Added for a better understanding]</p>
<p>Here is the full log of the corresponding POD</p>
<pre><code>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:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:21:27 Save Download Project : 
    id:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:21:27 [CloneBoilerplate] Start
2022/01/19 08:21:27 Already clone: [/home/guitou/app-generated/conf-61a867371b1331002c7595cc] 
 %!s(&lt;nil&gt;)
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 &amp;{0xc0003c2930}
2022/01/19 08:21:30 Project successfully clone  &amp;{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:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:21:30  john.doe@email.com
2022/01/19 08:21:30 Execute Project  id:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:21:30  john.doe@email.com
2022/01/19 08:21:30 Execute Project  id:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:21:30  john.doe@email.com
2022/01/19 08:21:30 Execute Project  id:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:21:30  john.doe@email.com
2022/01/19 08:21:30 Execute Project  id:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:21:30  john.doe@email.com
2022/01/19 08:21:30 Execute Project  id:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:21:30  john.doe@email.com
2022/01/19 08:21:30 Execute Project  id:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:21:30  john.doe@email.com
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] &quot;GET /61a867371b1331002c7595cc HTTP/1.1&quot; 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:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:22:27 Save Download Project : 
    id:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:22:27 [CloneBoilerplate] Start
2022/01/19 08:22:27 Already clone: [/home/guitou/app-generated/conf-61a867371b1331002c7595cc] 
 %!s(&lt;nil&gt;)
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 &amp;{0xc000596690}
2022/01/19 08:22:29 Project successfully clone  &amp;{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:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:22:29  john.doe@email.com
2022/01/19 08:22:29 Execute Project  id:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:22:29  john.doe@email.com
2022/01/19 08:22:29 Execute Project  id:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:22:29  john.doe@email.com
2022/01/19 08:22:29 Execute Project  id:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:22:29  john.doe@email.com
2022/01/19 08:22:29 Execute Project  id:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:22:29  john.doe@email.com
2022/01/19 08:22:29 Execute Project  id:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:22:29  john.doe@email.com
2022/01/19 08:22:29 Execute Project  id:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:22:29  john.doe@email.com
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] &quot;GET /61a867371b1331002c7595cc HTTP/1.1&quot; 408 18

************* RESTARTING HERE ***********************
2022/01/19 08:23:27 Grpc downloaded Project : 
     id:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:23:27 Save Download Project : 
    id:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:23:27 [CloneBoilerplate] Start
2022/01/19 08:23:27 Already clone: [/home/guitou/app-generated/conf-61a867371b1331002c7595cc] 
 %!s(&lt;nil&gt;)
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 &amp;{0xc0007928a0}
2022/01/19 08:23:30 Project successfully clone  &amp;{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:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:23:30  john.doe@email.com
2022/01/19 08:23:30 Execute Project  id:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:23:30  john.doe@email.com
2022/01/19 08:23:30 Execute Project  id:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:23:30  john.doe@email.com
2022/01/19 08:23:30 Execute Project  id:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:23:30  john.doe@email.com
2022/01/19 08:23:30 Execute Project  id:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:23:30  john.doe@email.com
2022/01/19 08:23:30 Execute Project  id:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:23:30  john.doe@email.com
2022/01/19 08:23:30 Execute Project  id:&quot;61a867371b1331002c7595cc&quot;  title:&quot;testing stufff&quot;  description:&quot;Go there&quot;  author:{email:&quot;john.doe@email.com&quot;}  xorms:{id:&quot;61a8673a1b1331002c7595d0&quot;  title:&quot;Xorm 1&quot;  level:&quot;primary&quot;}
2022/01/19 08:23:30  john.doe@email.com
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] &quot;GET /61a867371b1331002c7595cc HTTP/1.1&quot; 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 &quot;Install Android SDK Platform 29 (revision: 5)&quot;.
2022/01/19 08:25:51 [GENERATED_APK] r.ReadLine()  &quot;Install Android SDK Platform 29 (revision: 5)&quot; ready.
2022/01/19 08:25:51 [GENERATED_APK] r.ReadLine()  &quot;Install Android SDK Platform 29 (revision: 5)&quot; 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()  &gt; 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()  &gt; 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
</code></pre>
<p>Take a look at the section <code>********* STARTING HERE *****************</code> and <code>************* RESTARTING HERE ***********************</code> to notice that the handler it's restarting.</p>
<p>You can notice also that the even with the timeout the command <code>exec.CommandContext(&quot;flutter&quot;, &quot;build&quot;, &quot;appbundle&quot;)</code> is still running even after the context timeout.</p>
<p>Why such a behavior from <code>exec.CommandContext</code>?
How to stop the http handler after the context timeout ?</p>

Mael Fosso
<p>There's a couple of things of note:</p>
<ul>
<li>capturing <code>stdout</code> and <code>stderr</code> seems brittle (error handling from goroutine will not propagate properly)</li>
<li>long running executable may cause request timeout issues</li>
</ul>
<hr />
<p>to capture <code>stdout</code> and <code>stderr</code> - I'd suggest using something like <a href="https://cs.opensource.google/go/go/+/refs/tags/go1.17.6:src/os/exec/exec.go;l=557" rel="nofollow noreferrer">exec.Cmd.CombinedOutput</a> e.g.</p>
<pre><code>cmd := exec.CommandContext(ctx, &quot;flutter&quot;, &quot;build&quot;, &quot;appbundle&quot;) // see below for ctx details

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

outBody, errBody := string(sout.Bytes()), string(serr.Bytes())
</code></pre>
<p>so no need for tricky wait-groups or complex error handling between goroutines.</p>
<hr />
<p>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)</p>
<p>When running any webservice always ensure to leverage <code>context.Context</code> for the lifetime of a request - especially when running any potentially blocking operations (as you are with <code>exec.Command</code>).</p>
<p>So first, from your handler, grab the request's <code>context.Context</code>, and pass this along to any potentially blocking calls:</p>
<pre><code>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) // &lt;- add ctx
    }

}
</code></pre>
<p>and update your APK generator signature like so:</p>
<pre><code>func (app *MobileAPP) GenerateAPK(ctx context.Context, projectID string) (string, error)
</code></pre>
<p>and to use <code>ctx</code> when executing an external tool:</p>
<pre><code>//cmd := exec.Command(&quot;flutter&quot;, &quot;build&quot;, &quot;appbundle&quot;)
cmd := exec.CommandContext(ctx, &quot;flutter&quot;, &quot;build&quot;, &quot;appbundle&quot;)
</code></pre>
<p>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 <code>exec.CommandContext</code> for either <code>context.Canceled</code> (client disconnected) or <code>context.DeadlineExceeded</code> (request timed-out).</p>
