concurrency - Correct use of go context.Context -
i read article: build own web framework in go , sharing values among handlers picked context.context , i'm using in following way share values across handlers , middlewares:
type appcontext struct { db *sql.db ctx context.context cancel context.cancelfunc } func (c *appcontext)authhandler(next http.handler) http.handler { fn := func(w http.responsewriter, r *http.request { defer c.cancel() //this feels weird authtoken := r.header.get("authorization") // fakes form c.ctx = getuser(c.ctx, c.db, authtoken) // feels weird next.servehttp(w, r) } return http.handlerfunc(fn) } func (c *appcontext)adminhandler(w http.responsewriter, r *http.request) { defer c.cancel() user := c.ctx.value(0).(user) json.newencoder(w).encode(user) } func getuser(ctx context.context, db *sql.db, token string) context.context{ //this function mimics database access return context.withvalue(ctx, 0, user{nome:"default user"}) } func main() { db, err := sql.open("my-driver", "my.db") if err != nil { panic(err) } ctx, cancel := context.withcancel(context.background()) appc := appcontext{db, ctx, cancel} //.... }
everything working , handlers loading faster using gorilla/context questions are:
- is approach safe?
- is necessary defer c.cancel() function way i'm doing it?
- can use implement custom web framework using controllers struct share values models?
you have problem code because storing user app context. multiple users @ same time, doesn't work. context must related request not overwrote other requests. user must stored in request context. in articles use following gorilla function: context.set(r, "user", user)
. r
request.
if want use context.context
in app, should use gorilla wrapper (you can find @ end of article: https://blog.golang.org/context).
also, don't need context cancel. context.background()
okay root context.
Comments
Post a Comment