// Copyright (C) The Arvados Authors. All rights reserved. // // SPDX-License-Identifier: AGPL-3.0 package main import ( "net" "net/http" "sync" "time" "github.com/coreos/go-systemd/daemon" ) type server struct { httpServer *http.Server listener net.Listener wsConfig *wsConfig eventSource *pgEventSource setupOnce sync.Once } func (srv *server) Close() { srv.WaitReady() srv.eventSource.Close() srv.listener.Close() } func (srv *server) WaitReady() { srv.setupOnce.Do(srv.setup) srv.eventSource.WaitReady() } func (srv *server) Run() error { srv.setupOnce.Do(srv.setup) return srv.httpServer.Serve(srv.listener) } func (srv *server) setup() { log := logger(nil) ln, err := net.Listen("tcp", srv.wsConfig.Listen) if err != nil { log.WithField("Listen", srv.wsConfig.Listen).Fatal(err) } log.WithField("Listen", ln.Addr().String()).Info("listening") srv.listener = ln srv.eventSource = &pgEventSource{ DataSource: srv.wsConfig.Postgres.String(), MaxOpenConns: srv.wsConfig.PostgresPool, QueueSize: srv.wsConfig.ServerEventQueue, } srv.httpServer = &http.Server{ Addr: srv.wsConfig.Listen, ReadTimeout: time.Minute, WriteTimeout: time.Minute, MaxHeaderBytes: 1 << 20, Handler: &router{ Config: srv.wsConfig, eventSource: srv.eventSource, newPermChecker: func() permChecker { return newPermChecker(srv.wsConfig.Client) }, }, } go func() { srv.eventSource.Run() log.Info("event source stopped") srv.Close() }() if _, err := daemon.SdNotify(false, "READY=1"); err != nil { log.WithError(err).Warn("error notifying init daemon") } }