// NewRouter returns a new empty router instance. You will still need to call // ReloadRoutes() to do the initial route load. func NewRouter(mongoURL, mongoDbName, backendConnectTimeout, backendHeaderTimeout, logFileName string) (rt *Router, err error) { beConnTimeout, err := time.ParseDuration(backendConnectTimeout) if err != nil { return nil, err } beHeaderTimeout, err := time.ParseDuration(backendHeaderTimeout) if err != nil { return nil, err } logInfo("router: using backend connect timeout:", beConnTimeout) logInfo("router: using backend header timeout:", beHeaderTimeout) l, err := logger.New(logFileName) if err != nil { return nil, err } logInfo("router: logging errors as JSON to", logFileName) rt = &Router{ mux: triemux.NewMux(), mongoURL: mongoURL, mongoDbName: mongoDbName, backendConnectTimeout: beConnTimeout, backendHeaderTimeout: beHeaderTimeout, logger: l, } return rt, nil }
// ReloadRoutes reloads the routes for this Router instance on the fly. It will // create a new proxy mux, load applications (backends) and routes into it, and // then flip the "mux" pointer in the Router. func (rt *Router) ReloadRoutes() { defer func() { if r := recover(); r != nil { logWarn("router: recovered from panic in ReloadRoutes:", r) logInfo("router: original routes have not been modified") } }() logDebug("mgo: connecting to", rt.mongoURL) sess, err := mgo.Dial(rt.mongoURL) if err != nil { panic(fmt.Sprintln("mgo:", err)) } defer sess.Close() sess.SetMode(mgo.Strong, true) db := sess.DB(rt.mongoDbName) logInfo("router: reloading routes") newmux := triemux.NewMux() backends := rt.loadBackends(db.C("backends")) loadRoutes(db.C("routes"), newmux, backends) rt.lock.Lock() rt.mux = newmux rt.lock.Unlock() logInfo(fmt.Sprintf("router: reloaded %d routes (checksum: %x)", rt.mux.RouteCount(), rt.mux.RouteChecksum())) }
// ReloadRoutes reloads the routes for this Router instance on the fly. It will // create a new proxy mux, load applications (backends) and routes into it, and // then flip the "mux" pointer in the Router. func (rt *Router) ReloadRoutes() { // save a reference to the previous mux in case we have to restore it oldmux := rt.mux defer func() { if r := recover(); r != nil { logWarn("router: recovered from panic in ReloadRoutes:", r) rt.mux = oldmux logInfo("router: original routes have been restored") } }() logDebug("mgo: connecting to", rt.mongoUrl) sess, err := mgo.Dial(rt.mongoUrl) if err != nil { panic(fmt.Sprintln("mgo:", err)) } defer sess.Close() sess.SetMode(mgo.Strong, true) db := sess.DB(rt.mongoDbName) logInfo("router: reloading routes") newmux := triemux.NewMux() backends := rt.loadBackends(db.C("backends")) loadRoutes(db.C("routes"), newmux, backends) rt.mux = newmux logInfo(fmt.Sprintf("router: reloaded %d routes (checksum: %x)", rt.mux.RouteCount(), rt.mux.RouteChecksum())) }