563c91e7d5
Resolves issues with gcp cloud logging quirks such as field names
103 lines
2.7 KiB
Go
103 lines
2.7 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net"
|
|
"net/http"
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
|
|
"github.com/flowy-live/llink/internal/utils/flog"
|
|
|
|
"github.com/flowy-live/llink/internal"
|
|
"github.com/flowy-live/llink/internal/auth"
|
|
"github.com/flowy-live/llink/internal/db"
|
|
"github.com/flowy-live/llink/internal/network"
|
|
"github.com/flowy-live/llink/internal/pusher"
|
|
"github.com/flowy-live/llink/internal/utils"
|
|
|
|
"google.golang.org/grpc"
|
|
|
|
pbpusher "github.com/flowy-live/llink/genproto/llink/pusher"
|
|
)
|
|
|
|
func main() {
|
|
port := utils.MustGetEnv("PORT")
|
|
grpcPort := utils.MustGetEnv("GRPC_PORT")
|
|
|
|
db.Init()
|
|
defer db.Cleanup()
|
|
|
|
authRedis := internal.ConnectAndTestRedis(db.RedisDBAuth) // shared with orion
|
|
pusherRedis := internal.ConnectAndTestRedis(db.RedisDBPusher) // presence + pub/sub
|
|
|
|
sessionReader := auth.NewSessionReader(authRedis)
|
|
networkReader := network.NewReader(db.Pool())
|
|
|
|
// Hostname is the k8s pod name.
|
|
podID, err := os.Hostname()
|
|
if err != nil {
|
|
podID = fmt.Sprintf("pod-%d", os.Getpid())
|
|
}
|
|
|
|
bridge := pusher.NewRedisBridge(pusherRedis, podID)
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
|
|
authorizer := pusher.NewAuthorizer(networkReader)
|
|
hub := pusher.NewHub(bridge, authorizer)
|
|
bridge.SetHub(hub)
|
|
server := pusher.NewServer(ctx, hub, bridge, sessionReader)
|
|
|
|
go hub.Run(ctx)
|
|
go bridge.Listen(ctx)
|
|
go bridge.Heartbeat(ctx)
|
|
|
|
// --- gRPC server (internal presence queries) ---
|
|
grpcListener, err := net.Listen("tcp", fmt.Sprintf("0.0.0.0:%s", grpcPort))
|
|
if err != nil {
|
|
flog.Error("failed to listen for gRPC", "port", grpcPort, "error", err)
|
|
os.Exit(1)
|
|
}
|
|
grpcServer := grpc.NewServer()
|
|
pbpusher.RegisterPusherServiceServer(grpcServer, server)
|
|
go func() {
|
|
flog.Info("gRPC server listening", "port", grpcPort)
|
|
if err := grpcServer.Serve(grpcListener); err != nil {
|
|
flog.Error("gRPC server failed", "error", err)
|
|
}
|
|
}()
|
|
|
|
// --- HTTP server (WebSocket + health) ---
|
|
mux := http.NewServeMux()
|
|
mux.HandleFunc("GET /health", func(w http.ResponseWriter, r *http.Request) {
|
|
w.WriteHeader(http.StatusOK)
|
|
})
|
|
mux.HandleFunc("GET /ws", server.HandleWebSocket)
|
|
|
|
httpAddr := fmt.Sprintf("0.0.0.0:%s", port)
|
|
httpServer := &http.Server{Addr: httpAddr, Handler: mux}
|
|
|
|
go func() {
|
|
flog.Info("HTTP server listening", "addr", httpAddr)
|
|
if err := httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
|
flog.Error("HTTP server failed", "error", err)
|
|
os.Exit(1)
|
|
}
|
|
}()
|
|
|
|
// --- Graceful shutdown ---
|
|
sigCh := make(chan os.Signal, 1)
|
|
signal.Notify(sigCh, syscall.SIGTERM, syscall.SIGINT)
|
|
<-sigCh
|
|
|
|
flog.Info("shutting down...")
|
|
cancel()
|
|
|
|
grpcServer.GracefulStop()
|
|
httpServer.Shutdown(context.Background())
|
|
flog.Info("shutdown complete")
|
|
}
|