func main() { flag.Parse() if err := loadContext(); err != nil { panic(err) } ctx := context() expvar.Publish("config", &ctx.Config) expvar.Publish("codemanager", expvar.Func(func() interface{} { return context().InputManager })) expvar.Publish("queues", expvar.Func(func() interface{} { return context().QueueManager })) expvar.Publish("inflight_runs", expvar.Func(func() interface{} { return context().InflightMonitor })) cachePath := path.Join(ctx.Config.Grader.RuntimePath, "cache") go ctx.InputManager.PreloadInputs( cachePath, grader.NewGraderCachedInputFactory(cachePath), &sync.Mutex{}, ) // Database db, err := sql.Open( ctx.Config.Db.Driver, ctx.Config.Db.DataSourceName, ) if err != nil { panic(err) } if err := db.Ping(); err != nil { panic(err) } setupMetrics(ctx) ctx.Log.Info("omegaUp grader started") mux := http.DefaultServeMux if ctx.Config.Grader.V1.Enabled { registerV1CompatHandlers(mux, db) go common.RunServer(&ctx.Config.TLS, mux, ctx.Config.Grader.V1.Port, *insecure) mux = http.NewServeMux() } registerHandlers(mux, db) common.RunServer(&ctx.Config.TLS, mux, ctx.Config.Grader.Port, *insecure) }
func main() { flag.Parse() if err := loadContext(); err != nil { panic(err) } ctx := context() expvar.Publish("config", &ctx.Config) b := broadcaster.NewBroadcaster(ctx, &PrometheusMetrics{}) http.Handle("/metrics", prometheus.Handler()) http.HandleFunc("/deauthenticate/", func(w http.ResponseWriter, r *http.Request) { pathComponents := strings.Split(r.URL.Path, "/") if len(pathComponents) < 3 { w.WriteHeader(http.StatusBadRequest) return } b.Deauthenticate(pathComponents[2]) w.WriteHeader(http.StatusOK) }) http.HandleFunc("/broadcast/", func(w http.ResponseWriter, r *http.Request) { if *insecure { w.Header().Set("Access-Control-Methods", "POST") w.Header().Set("Access-Control-Allow-Origin", "*") } if r.Method != "POST" { w.WriteHeader(http.StatusBadRequest) return } defer r.Body.Close() var message broadcaster.Message decoder := json.NewDecoder(r.Body) if err := decoder.Decode(&message); err != nil { ctx.Log.Error("Error decoding broadcast message", "err", err) w.WriteHeader(http.StatusBadRequest) return } if !b.Broadcast(&message) { ctx.Log.Error("Error sending message, queue too large") w.WriteHeader(http.StatusServiceUnavailable) return } w.WriteHeader(http.StatusOK) }) eventsMux := http.NewServeMux() eventsMux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { ctx := context() authToken := "" if ouat, _ := r.Cookie("ouat"); ouat != nil { authToken = ouat.Value } var transport broadcaster.Transport if common.AcceptsMimeType(r, "text/event-stream") { transport = broadcaster.NewSSETransport(w) } else { conn, err := upgrader.Upgrade(w, r, nil) if err != nil { ctx.Log.Error("Failed to upgrade connection", "err", err) return } defer conn.Close() transport = broadcaster.NewWebSocketTransport( conn, ctx.Config.Broadcaster.WriteDeadline, ) } subscriber, err := broadcaster.NewSubscriber( ctx, authToken, strings.Join(r.URL.Query()["filter"], ","), transport, ) if err != nil { ctx.Log.Error("Failed to create subscriber", "err", err) if upstream, ok := err.(*broadcaster.UpstreamError); ok { w.WriteHeader(upstream.HTTPStatusCode) w.Write(upstream.Contents) } return } if !b.Subscribe(subscriber) { w.WriteHeader(http.StatusServiceUnavailable) return } defer b.Unsubscribe(subscriber) subscriber.Run() }) ctx.Log.Info("omegaUp broadcaster started", "port", ctx.Config.Broadcaster.EventsPort) go b.Run() go common.RunServer( &ctx.Config.Broadcaster.TLS, eventsMux, ctx.Config.Broadcaster.EventsPort, ctx.Config.Broadcaster.Proxied, ) common.RunServer(&ctx.Config.TLS, nil, ctx.Config.Broadcaster.Port, *insecure) }