diff options
Diffstat (limited to 'tvix/nar-bridge/pkg/server/server.go')
-rw-r--r-- | tvix/nar-bridge/pkg/server/server.go | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/tvix/nar-bridge/pkg/server/server.go b/tvix/nar-bridge/pkg/server/server.go new file mode 100644 index 000000000000..083b7f295a12 --- /dev/null +++ b/tvix/nar-bridge/pkg/server/server.go @@ -0,0 +1,86 @@ +package server + +import ( + "fmt" + "net/http" + "sync" + "time" + + storev1pb "code.tvl.fyi/tvix/store/protos" + "github.com/go-chi/chi/middleware" + "github.com/go-chi/chi/v5" + log "github.com/sirupsen/logrus" +) + +type Server struct { + handler chi.Router + + directoryServiceClient storev1pb.DirectoryServiceClient + blobServiceClient storev1pb.BlobServiceClient + pathInfoServiceClient storev1pb.PathInfoServiceClient + + // When uploading NAR files to a HTTP binary cache, the .nar + // files are uploaded before the .narinfo files. + // We need *both* to be able to fully construct a PathInfo object. + // Keep a in-memory map of narhash(es) (in SRI) to sparse PathInfo. + // This is necessary until we can ask a PathInfoService for a node with a given + // narSha256. + narHashToPathInfoMu sync.Mutex + narHashToPathInfo map[string]*storev1pb.PathInfo +} + +func New( + directoryServiceClient storev1pb.DirectoryServiceClient, + blobServiceClient storev1pb.BlobServiceClient, + pathInfoServiceClient storev1pb.PathInfoServiceClient, + enableAccessLog bool, + priority int, +) *Server { + r := chi.NewRouter() + + if enableAccessLog { + r.Use(middleware.Logger) + } + + r.Get("/", func(w http.ResponseWriter, r *http.Request) { + _, err := w.Write([]byte("nar-bridge")) + if err != nil { + log.Errorf("Unable to write response: %v", err) + } + }) + + r.Get("/nix-cache-info", func(w http.ResponseWriter, r *http.Request) { + _, err := w.Write([]byte(fmt.Sprintf("StoreDir: /nix/store\nWantMassQuery: 1\nPriority: %d\n", priority))) + if err != nil { + log.Errorf("Unable to write response: %v", err) + } + }) + + s := &Server{ + handler: r, + directoryServiceClient: directoryServiceClient, + blobServiceClient: blobServiceClient, + pathInfoServiceClient: pathInfoServiceClient, + narHashToPathInfo: make(map[string]*storev1pb.PathInfo), + } + + registerNarPut(s) + registerNarinfoPut(s) + + registerNarinfoGet(s) + registerNarGet(s) + + return s +} + +func (s *Server) ListenAndServe(addr string) error { + srv := &http.Server{ + Addr: addr, + Handler: s.handler, + ReadTimeout: 50 * time.Second, + WriteTimeout: 100 * time.Second, + IdleTimeout: 150 * time.Second, + } + + return srv.ListenAndServe() +} |