mirror of
https://github.com/foomo/contentserver.git
synced 2025-10-16 12:25:44 +00:00
143 lines
3.5 KiB
Go
143 lines
3.5 KiB
Go
package server
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net"
|
|
"net/http"
|
|
"os"
|
|
"time"
|
|
|
|
. "github.com/foomo/contentserver/logger"
|
|
"github.com/foomo/contentserver/repo"
|
|
jsoniter "github.com/json-iterator/go"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
var (
|
|
json = jsoniter.ConfigCompatibleWithStandardLibrary
|
|
)
|
|
|
|
// Handler type
|
|
type Handler string
|
|
|
|
const (
|
|
// HandlerGetURIs get uris, many at once, to keep it fast
|
|
HandlerGetURIs Handler = "getURIs"
|
|
// HandlerGetContent get (site) content
|
|
HandlerGetContent = "getContent"
|
|
// HandlerGetNodes get nodes
|
|
HandlerGetNodes = "getNodes"
|
|
// HandlerUpdate update repo
|
|
HandlerUpdate = "update"
|
|
// HandlerGetRepo get the whole repo
|
|
HandlerGetRepo = "getRepo"
|
|
|
|
// DefaultRepositoryTimeout for the HTTP client towards the repo
|
|
DefaultRepositoryTimeout = 2 * time.Minute
|
|
)
|
|
|
|
// Run - let it run and enjoy on a socket near you
|
|
func Run(server string, address string, varDir string, pollUpdates bool) error {
|
|
return RunServerSocketAndWebServer(server, address, "", "", varDir, DefaultRepositoryTimeout, pollUpdates)
|
|
}
|
|
|
|
func RunServerSocketAndWebServer(
|
|
server string,
|
|
address string,
|
|
webserverAddress string,
|
|
webserverPath string,
|
|
varDir string,
|
|
repositoryTimeout time.Duration,
|
|
pollForUpdates bool,
|
|
) error {
|
|
if address == "" && webserverAddress == "" {
|
|
return errors.New("one of the addresses needs to be set")
|
|
}
|
|
Log.Info("building repo with content", zap.String("server", server))
|
|
|
|
r := repo.NewRepo(server, varDir, repositoryTimeout, pollForUpdates)
|
|
|
|
// start initial update and handle error
|
|
if !pollForUpdates {
|
|
go func() {
|
|
resp := r.Update()
|
|
if !resp.Success {
|
|
Log.Error("failed to update",
|
|
zap.String("error", resp.ErrorMessage),
|
|
zap.Int("NumberOfNodes", resp.Stats.NumberOfNodes),
|
|
zap.Int("NumberOfURIs", resp.Stats.NumberOfURIs),
|
|
zap.Float64("OwnRuntime", resp.Stats.OwnRuntime),
|
|
zap.Float64("RepoRuntime", resp.Stats.RepoRuntime),
|
|
)
|
|
|
|
//Exit only if it hasn't recovered
|
|
if !r.Recovered() {
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
}()
|
|
}
|
|
|
|
// update can run in bg
|
|
chanErr := make(chan error)
|
|
|
|
if address != "" {
|
|
Log.Info("starting socketserver", zap.String("address", address))
|
|
go runSocketServer(r, address, chanErr)
|
|
}
|
|
if webserverAddress != "" {
|
|
Log.Info("starting webserver", zap.String("webserverAddress", webserverAddress))
|
|
go runWebserver(r, webserverAddress, webserverPath, chanErr)
|
|
}
|
|
return <-chanErr
|
|
}
|
|
|
|
func runWebserver(
|
|
r *repo.Repo,
|
|
address string,
|
|
path string,
|
|
chanErr chan error,
|
|
) {
|
|
chanErr <- http.ListenAndServe(address, NewWebServer(path, r))
|
|
}
|
|
|
|
func runSocketServer(
|
|
repo *repo.Repo,
|
|
address string,
|
|
chanErr chan error,
|
|
) {
|
|
// create socket server
|
|
s := newSocketServer(repo)
|
|
|
|
// listen on socket
|
|
ln, errListen := net.Listen("tcp", address)
|
|
if errListen != nil {
|
|
Log.Error("runSocketServer: could not start",
|
|
zap.String("address", address),
|
|
zap.Error(errListen),
|
|
)
|
|
chanErr <- errors.New("runSocketServer: could not start the on \"" + address + "\" - error: " + fmt.Sprint(errListen))
|
|
return
|
|
}
|
|
|
|
Log.Info("runSocketServer: started listening", zap.String("address", address))
|
|
for {
|
|
// this blocks until connection or error
|
|
conn, err := ln.Accept()
|
|
if err != nil {
|
|
Log.Error("runSocketServer: could not accept connection", zap.Error(err))
|
|
continue
|
|
}
|
|
|
|
// a goroutine handles conn so that the loop can accept other connections
|
|
go func() {
|
|
Log.Debug("accepted connection", zap.String("source", conn.RemoteAddr().String()))
|
|
s.handleConnection(conn)
|
|
conn.Close()
|
|
// log.Debug("connection closed")
|
|
}()
|
|
}
|
|
}
|