package main

// run this and then hit:
// http://localhost:6060/debug/pprof/
//
// Also run from the command line:
// go tool pprof 'localhost:6060/debug/pprof/wit_pprof_experiment_thing?debug=1'
//
// https://medium.com/@cep21/creating-custom-go-profiles-with-pprof-b737dfc58e11

import "fmt"
import "log"
import "net/http"
import _ "net/http/pprof" // the _ means only the init() is needed
import "os"
import "runtime/pprof"
import "sync/atomic"
import "time"

var libProfile *pprof.Profile

func init() {
	profName := "wit_pprof_experiment_thing" // this ends up in the URL
	libProfile = pprof.Lookup(profName)
	if libProfile == nil {
		libProfile = pprof.NewProfile(profName)
	}
}

type someResource struct {
	*os.File
}

var fileIndex = int64(0)

func MustResource() *someResource {
	f, err := os.Create(fmt.Sprintf("/tmp/%d.txt", atomic.AddInt64(&fileIndex, 1)))
	if err != nil {
		panic(err)
	}
	r := &someResource{f}
	libProfile.Add(r, 1)
	return r
}

func (r *someResource) Close() error {
	libProfile.Remove(r)
	return r.File.Close()
}

func trackAFunction() {
	tracked := new(byte)
	libProfile.Add(tracked, 1)
	defer libProfile.Remove(tracked)
	time.Sleep(time.Second)
}

func usesAResource() {
	res := MustResource()
	defer res.Close()
	for i := 0; i < 10; i++ {
		time.Sleep(time.Second)
	}
}

func main() {
	http.HandleFunc("/nonblock", func(rw http.ResponseWriter, req *http.Request) {
		go usesAResource()
	})
	http.HandleFunc("/functiontrack", func(rw http.ResponseWriter, req *http.Request) {
		trackAFunction()
	})
	http.HandleFunc("/block", func(rw http.ResponseWriter, req *http.Request) {
		usesAResource()
	})
	log.Println("run this and then hit:")
	log.Println("http://localhost:6060/debug/pprof/")
	log.Println("")
	log.Println("Running!")
	log.Println(http.ListenAndServe("localhost:6060", nil))
}