// ServeHTTP is called from the net/http system. You shouldn't need // to call this function func (app *App) ServeHTTP(w http.ResponseWriter, r *http.Request) { ctx := app.newContext(w, r) if profile.On && shouldProfile(ctx) { profile.Begin() defer profile.End(0) } defer app.closeContext(ctx) defer app.recover(ctx) if app.runProcessors(ctx) { return } app.serveOrNotFound(r.URL.Path, ctx) }
// Go spawns a new goroutine using a copy of the given Context // suitable for using after the request has been serviced // (id est, in goroutines spawned from the Handler which // might outlast the Handler's lifetime). Additionaly, Go also // handles error recovering and profiling in the spawned // goroutine. The initial Context can also wait for all // background contexts to finish by calling Wait(). // // In the following example, the handler finishes and returns the // executed template while CrunchData is still potentially running. // // func MyHandler(ctx *app.Context) { // data := AcquireData(ctx) // ctx.Go(func (c *app.Context) { // CrunchData(c, data) // note the usage of c rather than ctx // } // ctx.MustExecute("mytemplate.html", data) // } func (c *Context) Go(f func(*Context)) { if c.wg == nil { c.wg = new(sync.WaitGroup) } c.wg.Add(1) bg := c.backgroundContext() var id int if profile.On { id = profile.ID() } go func() { if profile.On { profile.Begin() defer profile.End(id) } defer bg.finalize(c.wg) f(bg) }() }