profiling http handler in go lang
<p>I am trying to profile my http handler written in go. Which on every http request download an image from S3, resize it/crop it and write it in response. </p>

<p>I have followed this <a href="http://saml.rilspace.org/profiling-and-creating-call-graphs-for-go-programs-with-go-tool-pprof#rest" rel="nofollow">link</a> and tried to profile my code as mentioned using easy method as well as hard method. Now, when i use the following line as mentioned in the code. </p>

<pre><code>defer profile.Start(profile.CPUProfile).Stop() 
</code></pre>

<p>It doesn't write anything in the <code>/tmp/profie[some number]/cpu.pprof</code> file</p>

<pre><code>func main() {                                    

       defer profile.Start(profile.CPUProfile).Stop()   

      if err := http.ListenAndServe(":8081", http.HandlerFunc(serveHTTP)); err != nil {
       logFatal("Error when starting or running http server: %v", err)
    }       
}

func serveHTTP(w http.ResponseWriter, r *http.Request) {
        keyName := r.URL.Path[1:]
        s3Client := s3.New(session.New(), &amp;aws.Config{Region: aws.String(region)})
        params := &amp;s3.GetObjectInput{
        Bucket: aws.String(bucketName),
        Key: aws.String(keyName),
        }

    mw := imagick.NewMagickWand()
    defer mw.Destroy()
    ...
}
</code></pre>

<p>Moreover, when i used the <code>defer profile.Start(profile.CPUProfile).Stop()</code> line inside the <code>serveHTTP</code> like :</p>

<pre><code>func serveHTTP(w http.ResponseWriter, r *http.Request) {

    defer profile.Start(profile.CPUProfile).Stop()
    ......
}
</code></pre>

<p>It creates multiple files in the <code>/tmp/profile[some number]</code> folder. So, first question is why it is not writing in the file and secondly shouldn't it be places inside the <code>serveHTTP method</code> because server will get started only once. Hence <code>main()</code> will be called once wheres <code>serveHTTP</code> wil be called on every request. </p>

<p>Part 1 </p>

<pre><code> .               124:   s3Client := s3.New(session.New(), &amp;aws.Config{Region: aws.String(region)})
 .          .    125:        params := &amp;s3.GetObjectInput{
 .          .    126:       Bucket: aws.String(masterBucketName),
 .          .    127:       Key: aws.String(keyName),
 .    32.01kB    128:       }
 .          .    129:
 .          .    130:   mw := imagick.NewMagickWand()
 .          .    131:   defer mw.Destroy()
 .          .    132:   
 .          .    133:   out, err := s3Client.GetObject(params)          
 .          .    134:
 .          .    135:   if strings.EqualFold(keyName[strings.LastIndex(keyName,".")+1:len(keyName)], "gif") {
 .          .    136:
 .    40.11kB    137:       blobGiff, err := ioutil.ReadAll(out.Body)
 .          .    138:       w.Header().Set("Content-Type", "image/gif")
 .          .    139:       w.Header().Set("Cache-Control", "max-age: 604800, public")  
 .          .    140:       w.Header().Set("Last-Modified", time.Now().Format(http.TimeFormat))
 .          .    141:       w.Header().Set("Expires", time.Now().AddDate(1, 0, 0).Format(http.TimeFormat))  
 .          .    142:
</code></pre>

<p>Part 2 :</p>

<pre><code>                                   else {
         .          .    167:       img, err := ioutil.ReadAll(out.Body)
         .          .    168:       if err != nil {
         .          .    169:          
         .          .    170:          w.WriteHeader(http.StatusNotFound) 
         .     1.56MB    171:          return      
         .          .    172:       }   
</code></pre>

<p>Also, in the above two parts line 128, 137 and 171 has memory leaks, right? Also, I don't find any option to close/destroy the <code>s3Client</code> and <code>blobGiff</code> (byte []). </p>