nyrf
(Nyrf)
October 4, 2015, 1:25pm
1
package main
import (
"github.com/gorilla/mux"
"net/http"
"reflect"
)
func main() {
r := mux.NewRouter()
r.HandleFunc("/", wrapController("Home", &TODO{}))
http.ListenAndServe(":3000", r)
}
// TODO
type TODO struct {
BaseController
}
func (t *TODO) Home() {
t.Response.Write([]byte("todo home"))
}
// Helper
func handleController(w http.ResponseWriter, req *http.Request, fn string, ctrl Controller) {
ctrl.New(w, req)
in := make([]reflect.Value, 0)
reflect.ValueOf(ctrl).MethodByName(fn).Call(in)
}
func wrapController(fn string, ctrl Controller) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, req *http.Request) {
handleController(w, req, fn, ctrl)
}
}
// Controller
type Controller interface {
New(http.ResponseWriter, *http.Request)
}
type BaseController struct {
Request *http.Request
Response http.ResponseWriter
}
func (b *BaseController) New(w http.ResponseWriter, r *http.Request) {
b.Request = r
b.Response = w
}
When run wrk -t12 -c900 -d10s http://localhost:3000
, got errors http: multiple response.WriteHeader calls
, i can’t find how to fix it,thanks.
matt
(Matt Holt)
October 4, 2015, 2:49pm
2
I suspect it’s because you’re using the same Controller for all requests. When you do &TODO{}
in your main(), that only creates one Controller and all requests share the same one.
By the way, this is very unusual Go code. Can I ask why you’re doing this?
nyrf
(Nyrf)
October 4, 2015, 2:57pm
3
I want to write a mini framework to learn go. I referenced some code from https://github.com/astaxie/beego
matt
(Matt Holt)
October 4, 2015, 3:03pm
4
Run your program with the -race
flag and see if it finds any race conditions first. I’m suspicious of that Controller.
nyrf
(Nyrf)
October 4, 2015, 3:15pm
5
matt:
-race
Thanks, i tried, but nothing happend,
nyrf
(Nyrf)
October 4, 2015, 3:52pm
6
Solved. Use sync.RWMutex
can fix this.Thanks.
matt
(Matt Holt)
October 4, 2015, 4:32pm
7
Remember to mark your reply as the answer (click the chrck mark) so others who find this thread can find the answer quickly
elithrar
(Matt Silverlock)
October 4, 2015, 9:06pm
9
This is a very odd design (as @mholt points out) - in fact, it’s pretty dangerous as you have one controller instance and will leak data across requests (as you are finding out).
Sharing the same controller across requests is not how to write a Go HTTP server.
Take a look at these articles and move away from the “Controller” pattern —which doesn’t port well to Go, as you’re finding:
2 Likes
nyrf
(Nyrf)
October 5, 2015, 4:12pm
10
system
(system)
Closed
January 3, 2016, 4:13pm
11
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.