about summary refs log tree commit diff
path: root/tvix
diff options
context:
space:
mode:
authorConnor Brewster <cbrewster@hey.com>2023-09-23T00·45-0500
committerConnor Brewster <cbrewster@hey.com>2023-09-25T17·41+0000
commitf8746fcab0d6cbd6d9e7a49ce2217f858151a476 (patch)
tree5d1f66dda725b8ae0bc5c6d8ec7ab430bf9955f1 /tvix
parent1b3d6975ed8c2a19f1e7f4f39a564cdfa387f0b6 (diff)
feat(tvix/store): Support listening on UNIX domain sockets r/6653
This adds support for listening on UNIX domain sockets via the
tokio-listener crate. The crate will automatically determine whether to
start a TCP or UNIX domain socket server based on the listen address.

Unfortunately, it's not compatible with tonic right out of the box so I
added some wrapper types to implement the necessary traits to make
things work. We should investigate upstreaming a `tonic` option to the
tokio-listener crate which implements the relevant `tonic` traits.

Example:
```
$ tvix-store daemon -l /run/tvix-store.sock
INFO tvix_store: tvix-store listening on /run/tvix-store.sock

$ tvix-store mount -l /mnt/tvix --blob-service-addr grpc+unix:///run/tvix-store.sock --directory-service-addr grpc+unix:///run/tvix-store.sock --path-info-service-addr grpc+unix:///run/tvix-store.sock

$ ls /mnt/tvix
```

Change-Id: I91c4a4b0c5a177b3b90e6c01a4e5d263130e6bdb
Reviewed-on: https://cl.tvl.fyi/c/depot/+/9429
Tested-by: BuildkiteCI
Reviewed-by: flokli <flokli@flokli.de>
Reviewed-by: raitobezarius <tvl@lahfa.xyz>
Diffstat (limited to 'tvix')
-rw-r--r--tvix/Cargo.lock109
-rw-r--r--tvix/Cargo.nix228
-rw-r--r--tvix/store/Cargo.toml1
-rw-r--r--tvix/store/src/bin/tvix-store.rs5
-rw-r--r--tvix/store/src/lib.rs1
-rw-r--r--tvix/store/src/listener/mod.rs115
6 files changed, 388 insertions, 71 deletions
diff --git a/tvix/Cargo.lock b/tvix/Cargo.lock
index 6b5f12f949..d4a8fec84a 100644
--- a/tvix/Cargo.lock
+++ b/tvix/Cargo.lock
@@ -122,7 +122,7 @@ version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
 dependencies = [
- "proc-macro2 1.0.56",
+ "proc-macro2 1.0.67",
  "quote 1.0.26",
  "syn 2.0.15",
 ]
@@ -133,7 +133,7 @@ version = "0.1.68"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842"
 dependencies = [
- "proc-macro2 1.0.56",
+ "proc-macro2 1.0.67",
  "quote 1.0.26",
  "syn 2.0.15",
 ]
@@ -402,7 +402,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4"
 dependencies = [
  "heck",
- "proc-macro2 1.0.56",
+ "proc-macro2 1.0.67",
  "quote 1.0.26",
  "syn 2.0.15",
 ]
@@ -662,6 +662,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "document-features"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e493c573fce17f00dcab13b6ac057994f3ce17d1af4dc39bfd482b83c6eb6157"
+dependencies = [
+ "litrs",
+]
+
+[[package]]
 name = "either"
 version = "1.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -835,7 +844,7 @@ version = "0.3.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
 dependencies = [
- "proc-macro2 1.0.56",
+ "proc-macro2 1.0.67",
  "quote 1.0.26",
  "syn 2.0.15",
 ]
@@ -1024,9 +1033,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
 
 [[package]]
 name = "hyper"
-version = "0.14.26"
+version = "0.14.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4"
+checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468"
 dependencies = [
  "bytes",
  "futures-channel",
@@ -1256,6 +1265,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f"
 
 [[package]]
+name = "litrs"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f9275e0933cf8bb20f008924c0cb07a0692fe54d8064996520bf998de9eb79aa"
+
+[[package]]
 name = "lock_api"
 version = "0.4.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1371,6 +1386,17 @@ dependencies = [
 ]
 
 [[package]]
+name = "nix"
+version = "0.26.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b"
+dependencies = [
+ "bitflags",
+ "cfg-if",
+ "libc",
+]
+
+[[package]]
 name = "nix-cli"
 version = "0.1.0"
 dependencies = [
@@ -1545,22 +1571,22 @@ dependencies = [
 
 [[package]]
 name = "pin-project"
-version = "1.0.12"
+version = "1.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc"
+checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422"
 dependencies = [
  "pin-project-internal",
 ]
 
 [[package]]
 name = "pin-project-internal"
-version = "1.0.12"
+version = "1.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55"
+checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
 dependencies = [
- "proc-macro2 1.0.56",
+ "proc-macro2 1.0.67",
  "quote 1.0.26",
- "syn 1.0.109",
+ "syn 2.0.15",
 ]
 
 [[package]]
@@ -1627,7 +1653,7 @@ version = "0.1.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86"
 dependencies = [
- "proc-macro2 1.0.56",
+ "proc-macro2 1.0.67",
  "syn 1.0.109",
 ]
 
@@ -1638,7 +1664,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
 dependencies = [
  "proc-macro-error-attr",
- "proc-macro2 1.0.56",
+ "proc-macro2 1.0.67",
  "quote 1.0.26",
  "syn 1.0.109",
  "version_check",
@@ -1650,7 +1676,7 @@ version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
 dependencies = [
- "proc-macro2 1.0.56",
+ "proc-macro2 1.0.67",
  "quote 1.0.26",
  "version_check",
 ]
@@ -1666,9 +1692,9 @@ dependencies = [
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.56"
+version = "1.0.67"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
+checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328"
 dependencies = [
  "unicode-ident",
 ]
@@ -1734,7 +1760,7 @@ checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4"
 dependencies = [
  "anyhow",
  "itertools",
- "proc-macro2 1.0.56",
+ "proc-macro2 1.0.67",
  "quote 1.0.26",
  "syn 1.0.109",
 ]
@@ -1775,7 +1801,7 @@ version = "1.0.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
 dependencies = [
- "proc-macro2 1.0.56",
+ "proc-macro2 1.0.67",
 ]
 
 [[package]]
@@ -2087,7 +2113,7 @@ version = "1.0.162"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a2a0814352fd64b58489904a44ea8d90cb1a91dcb6b4f5ebabc32c8318e93cb6"
 dependencies = [
- "proc-macro2 1.0.56",
+ "proc-macro2 1.0.67",
  "quote 1.0.26",
  "syn 2.0.15",
 ]
@@ -2226,7 +2252,7 @@ version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "104842d6278bf64aa9d2f182ba4bde31e8aec7a131d29b7f444bb9b344a09e2a"
 dependencies = [
- "proc-macro2 1.0.56",
+ "proc-macro2 1.0.67",
  "quote 1.0.26",
  "structmeta-derive",
  "syn 1.0.109",
@@ -2238,7 +2264,7 @@ version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "24420be405b590e2d746d83b01f09af673270cf80e9b003a5fa7b651c58c7d93"
 dependencies = [
- "proc-macro2 1.0.56",
+ "proc-macro2 1.0.67",
  "quote 1.0.26",
  "syn 1.0.109",
 ]
@@ -2266,7 +2292,7 @@ version = "1.0.109"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
 dependencies = [
- "proc-macro2 1.0.56",
+ "proc-macro2 1.0.67",
  "quote 1.0.26",
  "unicode-ident",
 ]
@@ -2277,7 +2303,7 @@ version = "2.0.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822"
 dependencies = [
- "proc-macro2 1.0.56",
+ "proc-macro2 1.0.67",
  "quote 1.0.26",
  "unicode-ident",
 ]
@@ -2346,7 +2372,7 @@ checksum = "e45b7bf6e19353ddd832745c8fcf77a17a93171df7151187f26623f2b75b5b26"
 dependencies = [
  "cfg-if",
  "proc-macro-error",
- "proc-macro2 1.0.56",
+ "proc-macro2 1.0.67",
  "quote 1.0.26",
  "syn 1.0.109",
 ]
@@ -2368,7 +2394,7 @@ version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "62d6408d1406657be2f9d1701fbae379331d30d2f6e92050710edb0d34eeb480"
 dependencies = [
- "proc-macro2 1.0.56",
+ "proc-macro2 1.0.67",
  "quote 1.0.26",
  "structmeta",
  "syn 1.0.109",
@@ -2401,7 +2427,7 @@ version = "1.0.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
 dependencies = [
- "proc-macro2 1.0.56",
+ "proc-macro2 1.0.67",
  "quote 1.0.26",
  "syn 2.0.15",
 ]
@@ -2470,12 +2496,28 @@ dependencies = [
 ]
 
 [[package]]
+name = "tokio-listener"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05875e290052a679fec29aef1da57eb4da3dafb59c6fe579fb143ccca3dea7fb"
+dependencies = [
+ "document-features",
+ "futures-core",
+ "hyper",
+ "nix 0.26.4",
+ "pin-project",
+ "socket2 0.5.4",
+ "tokio",
+ "tracing",
+]
+
+[[package]]
 name = "tokio-macros"
 version = "2.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
 dependencies = [
- "proc-macro2 1.0.56",
+ "proc-macro2 1.0.67",
  "quote 1.0.26",
  "syn 2.0.15",
 ]
@@ -2578,7 +2620,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5bf5e9b9c0f7e0a7c027dcfaba7b2c60816c7049171f679d99ee2ff65d0de8c4"
 dependencies = [
  "prettyplease",
- "proc-macro2 1.0.56",
+ "proc-macro2 1.0.67",
  "prost-build",
  "quote 1.0.26",
  "syn 1.0.109",
@@ -2663,7 +2705,7 @@ version = "0.1.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74"
 dependencies = [
- "proc-macro2 1.0.56",
+ "proc-macro2 1.0.67",
  "quote 1.0.26",
  "syn 2.0.15",
 ]
@@ -2816,7 +2858,7 @@ dependencies = [
 name = "tvix-eval-builtin-macros"
 version = "0.0.1"
 dependencies = [
- "proc-macro2 1.0.56",
+ "proc-macro2 1.0.67",
  "quote 1.0.26",
  "syn 1.0.109",
  "tvix-eval",
@@ -2856,6 +2898,7 @@ dependencies = [
  "test-case",
  "thiserror",
  "tokio",
+ "tokio-listener",
  "tokio-stream",
  "tokio-util",
  "tonic",
@@ -3082,7 +3125,7 @@ dependencies = [
  "bumpalo",
  "log",
  "once_cell",
- "proc-macro2 1.0.56",
+ "proc-macro2 1.0.67",
  "quote 1.0.26",
  "syn 1.0.109",
  "wasm-bindgen-shared",
@@ -3104,7 +3147,7 @@ version = "0.2.84"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6"
 dependencies = [
- "proc-macro2 1.0.56",
+ "proc-macro2 1.0.67",
  "quote 1.0.26",
  "syn 1.0.109",
  "wasm-bindgen-backend",
diff --git a/tvix/Cargo.nix b/tvix/Cargo.nix
index 43cd31c91f..8f7686ce5c 100644
--- a/tvix/Cargo.nix
+++ b/tvix/Cargo.nix
@@ -417,7 +417,7 @@ rec {
         dependencies = [
           {
             name = "proc-macro2";
-            packageId = "proc-macro2 1.0.56";
+            packageId = "proc-macro2 1.0.67";
           }
           {
             name = "quote";
@@ -443,7 +443,7 @@ rec {
         dependencies = [
           {
             name = "proc-macro2";
-            packageId = "proc-macro2 1.0.56";
+            packageId = "proc-macro2 1.0.67";
           }
           {
             name = "quote";
@@ -1259,7 +1259,7 @@ rec {
           }
           {
             name = "proc-macro2";
-            packageId = "proc-macro2 1.0.56";
+            packageId = "proc-macro2 1.0.67";
           }
           {
             name = "quote";
@@ -1921,6 +1921,26 @@ rec {
         ];
 
       };
+      "document-features" = rec {
+        crateName = "document-features";
+        version = "0.2.7";
+        edition = "2018";
+        sha256 = "0mv1xg386as8zndw6kdgs4bwxwwlg42srdhkmgf00zz1zirwb4z4";
+        procMacro = true;
+        libPath = "lib.rs";
+        authors = [
+          "Slint Developers <info@slint-ui.com>"
+        ];
+        dependencies = [
+          {
+            name = "litrs";
+            packageId = "litrs";
+            usesDefaultFeatures = false;
+          }
+        ];
+        features = { };
+        resolvedDefaultFeatures = [ "default" ];
+      };
       "either" = rec {
         crateName = "either";
         version = "1.8.1";
@@ -2421,7 +2441,7 @@ rec {
         dependencies = [
           {
             name = "proc-macro2";
-            packageId = "proc-macro2 1.0.56";
+            packageId = "proc-macro2 1.0.67";
           }
           {
             name = "quote";
@@ -2946,9 +2966,9 @@ rec {
       };
       "hyper" = rec {
         crateName = "hyper";
-        version = "0.14.26";
+        version = "0.14.27";
         edition = "2018";
-        sha256 = "1m27s4p6kv5rbzqkw2lzfs60fwz7wym97zri0j8kn6pilrr2sc5b";
+        sha256 = "0s2l74p3harvjgb0bvaxlxgxq71vpfrzv0cqz2p9w8d8akbczcgz";
         authors = [
           "Sean McArthur <sean@seanmonstar.com>"
         ];
@@ -3691,6 +3711,19 @@ rec {
         };
         resolvedDefaultFeatures = [ "errno" "general" "ioctl" "no_std" ];
       };
+      "litrs" = rec {
+        crateName = "litrs";
+        version = "0.2.3";
+        edition = "2018";
+        sha256 = "1akrxglqv6dz41jrjr409pjjysd00z5w0949007v52yg6c4mw9zr";
+        authors = [
+          "Lukas Kalbertodt <lukas.kalbertodt@gmail.com>"
+        ];
+        features = {
+          "default" = [ "proc-macro2" ];
+          "proc-macro2" = [ "dep:proc-macro2" ];
+        };
+      };
       "lock_api" = rec {
         crateName = "lock_api";
         version = "0.4.9";
@@ -4008,6 +4041,48 @@ rec {
         };
         resolvedDefaultFeatures = [ "fs" "ioctl" "poll" "process" "signal" "term" ];
       };
+      "nix 0.26.4" = rec {
+        crateName = "nix";
+        version = "0.26.4";
+        edition = "2018";
+        sha256 = "06xgl4ybb8pvjrbmc3xggbgk3kbs1j0c4c0nzdfrmpbgrkrym2sr";
+        authors = [
+          "The nix-rust Project Developers"
+        ];
+        dependencies = [
+          {
+            name = "bitflags";
+            packageId = "bitflags";
+          }
+          {
+            name = "cfg-if";
+            packageId = "cfg-if";
+          }
+          {
+            name = "libc";
+            packageId = "libc";
+            features = [ "extra_traits" ];
+          }
+        ];
+        features = {
+          "aio" = [ "pin-utils" ];
+          "default" = [ "acct" "aio" "dir" "env" "event" "feature" "fs" "hostname" "inotify" "ioctl" "kmod" "mman" "mount" "mqueue" "net" "personality" "poll" "process" "pthread" "ptrace" "quota" "reboot" "resource" "sched" "signal" "socket" "term" "time" "ucontext" "uio" "user" "zerocopy" ];
+          "dir" = [ "fs" ];
+          "memoffset" = [ "dep:memoffset" ];
+          "mount" = [ "uio" ];
+          "mqueue" = [ "fs" ];
+          "net" = [ "socket" ];
+          "pin-utils" = [ "dep:pin-utils" ];
+          "ptrace" = [ "process" ];
+          "sched" = [ "process" ];
+          "signal" = [ "process" ];
+          "socket" = [ "memoffset" ];
+          "ucontext" = [ "signal" ];
+          "user" = [ "feature" ];
+          "zerocopy" = [ "fs" "uio" ];
+        };
+        resolvedDefaultFeatures = [ "feature" "fs" "user" ];
+      };
       "nix-cli" = rec {
         crateName = "nix-cli";
         version = "0.1.0";
@@ -4501,9 +4576,9 @@ rec {
       };
       "pin-project" = rec {
         crateName = "pin-project";
-        version = "1.0.12";
-        edition = "2018";
-        sha256 = "1k3f9jkia3idxl2pqxamszwnl89dk52fa4jqj3p7zmmwnq4scadd";
+        version = "1.1.3";
+        edition = "2021";
+        sha256 = "08k4cpy8q3j93qqgnrbzkcgpn7g0a88l4a9nm33kyghpdhffv97x";
         dependencies = [
           {
             name = "pin-project-internal";
@@ -4514,14 +4589,14 @@ rec {
       };
       "pin-project-internal" = rec {
         crateName = "pin-project-internal";
-        version = "1.0.12";
-        edition = "2018";
-        sha256 = "0maa6icn7rdfy4xvgfaq7m7bwpw9f19wg76f1ncsiixd0lgdp6q6";
+        version = "1.1.3";
+        edition = "2021";
+        sha256 = "01a4l3vb84brv9v7wl71chzxra2kynm6yvcjca66xv3ij6fgsna3";
         procMacro = true;
         dependencies = [
           {
             name = "proc-macro2";
-            packageId = "proc-macro2 1.0.56";
+            packageId = "proc-macro2 1.0.67";
           }
           {
             name = "quote";
@@ -4529,7 +4604,7 @@ rec {
           }
           {
             name = "syn";
-            packageId = "syn 1.0.109";
+            packageId = "syn 2.0.15";
             features = [ "full" "visit-mut" ];
           }
         ];
@@ -4698,7 +4773,7 @@ rec {
         dependencies = [
           {
             name = "proc-macro2";
-            packageId = "proc-macro2 1.0.56";
+            packageId = "proc-macro2 1.0.67";
             usesDefaultFeatures = false;
           }
           {
@@ -4735,7 +4810,7 @@ rec {
           }
           {
             name = "proc-macro2";
-            packageId = "proc-macro2 1.0.56";
+            packageId = "proc-macro2 1.0.67";
           }
           {
             name = "quote";
@@ -4773,7 +4848,7 @@ rec {
         dependencies = [
           {
             name = "proc-macro2";
-            packageId = "proc-macro2 1.0.56";
+            packageId = "proc-macro2 1.0.67";
           }
           {
             name = "quote";
@@ -4807,11 +4882,11 @@ rec {
         };
         resolvedDefaultFeatures = [ "default" "proc-macro" ];
       };
-      "proc-macro2 1.0.56" = rec {
+      "proc-macro2 1.0.67" = rec {
         crateName = "proc-macro2";
-        version = "1.0.56";
-        edition = "2018";
-        sha256 = "0ddlk2c7s9c0fhmf8cd0wikayicv9xrm9ck9vzgg9w86rnqbsqrb";
+        version = "1.0.67";
+        edition = "2021";
+        sha256 = "0a0k7adv0yswsgzsqkd7r6ng8rpcdyqrhra5v5ii531y3agkshrx";
         authors = [
           "David Tolnay <dtolnay@gmail.com>"
           "Alex Crichton <alex@alexcrichton.com>"
@@ -5062,7 +5137,7 @@ rec {
           }
           {
             name = "proc-macro2";
-            packageId = "proc-macro2 1.0.56";
+            packageId = "proc-macro2 1.0.67";
           }
           {
             name = "quote";
@@ -5154,7 +5229,7 @@ rec {
         dependencies = [
           {
             name = "proc-macro2";
-            packageId = "proc-macro2 1.0.56";
+            packageId = "proc-macro2 1.0.67";
             usesDefaultFeatures = false;
           }
         ];
@@ -6101,7 +6176,7 @@ rec {
         dependencies = [
           {
             name = "proc-macro2";
-            packageId = "proc-macro2 1.0.56";
+            packageId = "proc-macro2 1.0.67";
           }
           {
             name = "quote";
@@ -6473,7 +6548,7 @@ rec {
         dependencies = [
           {
             name = "proc-macro2";
-            packageId = "proc-macro2 1.0.56";
+            packageId = "proc-macro2 1.0.67";
           }
           {
             name = "quote";
@@ -6509,7 +6584,7 @@ rec {
         dependencies = [
           {
             name = "proc-macro2";
-            packageId = "proc-macro2 1.0.56";
+            packageId = "proc-macro2 1.0.67";
           }
           {
             name = "quote";
@@ -6586,7 +6661,7 @@ rec {
         dependencies = [
           {
             name = "proc-macro2";
-            packageId = "proc-macro2 1.0.56";
+            packageId = "proc-macro2 1.0.67";
             usesDefaultFeatures = false;
           }
           {
@@ -6620,7 +6695,7 @@ rec {
         dependencies = [
           {
             name = "proc-macro2";
-            packageId = "proc-macro2 1.0.56";
+            packageId = "proc-macro2 1.0.67";
             usesDefaultFeatures = false;
           }
           {
@@ -6798,7 +6873,7 @@ rec {
           }
           {
             name = "proc-macro2";
-            packageId = "proc-macro2 1.0.56";
+            packageId = "proc-macro2 1.0.67";
           }
           {
             name = "quote";
@@ -6859,7 +6934,7 @@ rec {
         dependencies = [
           {
             name = "proc-macro2";
-            packageId = "proc-macro2 1.0.56";
+            packageId = "proc-macro2 1.0.67";
           }
           {
             name = "quote";
@@ -6935,7 +7010,7 @@ rec {
         dependencies = [
           {
             name = "proc-macro2";
-            packageId = "proc-macro2 1.0.56";
+            packageId = "proc-macro2 1.0.67";
           }
           {
             name = "quote";
@@ -7158,6 +7233,81 @@ rec {
         ];
 
       };
+      "tokio-listener" = rec {
+        crateName = "tokio-listener";
+        version = "0.2.1";
+        edition = "2021";
+        sha256 = "1yx7vsiwqg0lzdwyavwwnnpkvnmlgsjivvwsqbz7k9jj00lmx1q5";
+        dependencies = [
+          {
+            name = "document-features";
+            packageId = "document-features";
+          }
+          {
+            name = "futures-core";
+            packageId = "futures-core";
+          }
+          {
+            name = "hyper";
+            packageId = "hyper";
+            optional = true;
+            features = [ "server" ];
+          }
+          {
+            name = "nix";
+            packageId = "nix 0.26.4";
+            optional = true;
+            usesDefaultFeatures = false;
+            target = { target, features }: (target."unix" or false);
+            features = [ "user" "fs" ];
+          }
+          {
+            name = "pin-project";
+            packageId = "pin-project";
+          }
+          {
+            name = "socket2";
+            packageId = "socket2 0.5.4";
+            optional = true;
+            features = [ "all" ];
+          }
+          {
+            name = "tokio";
+            packageId = "tokio";
+            features = [ "net" "io-std" "time" "sync" ];
+          }
+          {
+            name = "tracing";
+            packageId = "tracing";
+          }
+        ];
+        devDependencies = [
+          {
+            name = "hyper";
+            packageId = "hyper";
+            features = [ "server" "http1" ];
+          }
+          {
+            name = "tokio";
+            packageId = "tokio";
+            features = [ "macros" "rt" "io-util" ];
+          }
+        ];
+        features = {
+          "clap" = [ "dep:clap" ];
+          "default" = [ "hyper014" "user_facing_default" ];
+          "hyper" = [ "dep:hyper" ];
+          "hyper014" = [ "hyper" ];
+          "nix" = [ "dep:nix" ];
+          "serde" = [ "dep:serde" "serde_with" ];
+          "serde_with" = [ "dep:serde_with" ];
+          "socket2" = [ "dep:socket2" ];
+          "socket_options" = [ "socket2" ];
+          "unix_path_tools" = [ "nix" ];
+          "user_facing_default" = [ "inetd" "unix" "unix_path_tools" "sd_listen" "socket_options" ];
+        };
+        resolvedDefaultFeatures = [ "default" "hyper" "hyper014" "inetd" "nix" "sd_listen" "socket2" "socket_options" "unix" "unix_path_tools" "user_facing_default" ];
+      };
       "tokio-macros" = rec {
         crateName = "tokio-macros";
         version = "2.1.0";
@@ -7170,7 +7320,7 @@ rec {
         dependencies = [
           {
             name = "proc-macro2";
-            packageId = "proc-macro2 1.0.56";
+            packageId = "proc-macro2 1.0.67";
           }
           {
             name = "quote";
@@ -7577,7 +7727,7 @@ rec {
           }
           {
             name = "proc-macro2";
-            packageId = "proc-macro2 1.0.56";
+            packageId = "proc-macro2 1.0.67";
           }
           {
             name = "prost-build";
@@ -7895,7 +8045,7 @@ rec {
         dependencies = [
           {
             name = "proc-macro2";
-            packageId = "proc-macro2 1.0.56";
+            packageId = "proc-macro2 1.0.67";
           }
           {
             name = "quote";
@@ -8484,7 +8634,7 @@ rec {
         dependencies = [
           {
             name = "proc-macro2";
-            packageId = "proc-macro2 1.0.56";
+            packageId = "proc-macro2 1.0.67";
           }
           {
             name = "quote";
@@ -8629,6 +8779,10 @@ rec {
             features = [ "fs" "net" "rt-multi-thread" "signal" ];
           }
           {
+            name = "tokio-listener";
+            packageId = "tokio-listener";
+          }
+          {
             name = "tokio-stream";
             packageId = "tokio-stream";
             features = [ "fs" ];
@@ -9246,7 +9400,7 @@ rec {
           }
           {
             name = "proc-macro2";
-            packageId = "proc-macro2 1.0.56";
+            packageId = "proc-macro2 1.0.67";
           }
           {
             name = "quote";
@@ -9303,7 +9457,7 @@ rec {
         dependencies = [
           {
             name = "proc-macro2";
-            packageId = "proc-macro2 1.0.56";
+            packageId = "proc-macro2 1.0.67";
           }
           {
             name = "quote";
diff --git a/tvix/store/Cargo.toml b/tvix/store/Cargo.toml
index 20909221c5..05b3f4c863 100644
--- a/tvix/store/Cargo.toml
+++ b/tvix/store/Cargo.toml
@@ -30,6 +30,7 @@ tracing-subscriber = { version = "0.3.16", features = ["json"] }
 tvix-castore = { path = "../castore" }
 url = "2.4.0"
 walkdir = "2.4.0"
+tokio-listener = { version = "0.2.1" }
 
 [dependencies.fuse-backend-rs]
 optional = true
diff --git a/tvix/store/src/bin/tvix-store.rs b/tvix/store/src/bin/tvix-store.rs
index 813d62cb12..e80014047c 100644
--- a/tvix/store/src/bin/tvix-store.rs
+++ b/tvix/store/src/bin/tvix-store.rs
@@ -17,6 +17,7 @@ use tvix_castore::proto::node::Node;
 use tvix_castore::proto::GRPCBlobServiceWrapper;
 use tvix_castore::proto::GRPCDirectoryServiceWrapper;
 use tvix_castore::proto::NamedNode;
+use tvix_store::listener::ListenerStream;
 use tvix_store::pathinfoservice;
 use tvix_store::proto::path_info_service_server::PathInfoServiceServer;
 use tvix_store::proto::GRPCPathInfoServiceWrapper;
@@ -220,7 +221,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
 
             info!("tvix-store listening on {}", listen_address);
 
-            router.serve(listen_address).await?;
+            let listener = ListenerStream::bind(&listen_address).await?;
+
+            router.serve_with_incoming(listener).await?;
         }
         Commands::Import {
             paths,
diff --git a/tvix/store/src/lib.rs b/tvix/store/src/lib.rs
index c591214533..c988e14717 100644
--- a/tvix/store/src/lib.rs
+++ b/tvix/store/src/lib.rs
@@ -1,6 +1,7 @@
 #[cfg(feature = "fs")]
 pub mod fs;
 
+pub mod listener;
 pub mod nar;
 pub mod pathinfoservice;
 pub mod proto;
diff --git a/tvix/store/src/listener/mod.rs b/tvix/store/src/listener/mod.rs
new file mode 100644
index 0000000000..3a44a0511c
--- /dev/null
+++ b/tvix/store/src/listener/mod.rs
@@ -0,0 +1,115 @@
+use std::{
+    io,
+    ops::{Deref, DerefMut},
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use futures::Stream;
+use pin_project_lite::pin_project;
+use tokio::io::{AsyncRead, AsyncWrite};
+use tokio_listener::{Listener, ListenerAddress};
+use tonic::transport::server::Connected;
+
+/// A wrapper around a [Listener] which implements the [Stream] trait.
+/// Mainly used to bridge [tokio_listener] with [tonic].
+pub struct ListenerStream {
+    inner: Listener,
+}
+
+impl ListenerStream {
+    /// Convert a [Listener] into a [Stream].
+    pub fn new(inner: Listener) -> Self {
+        Self { inner }
+    }
+
+    /// Binds to the specified address and returns a [Stream] of connections.
+    pub async fn bind(addr: &ListenerAddress) -> io::Result<Self> {
+        let listener = Listener::bind(addr, &Default::default(), &Default::default()).await?;
+
+        Ok(Self::new(listener))
+    }
+}
+
+impl Stream for ListenerStream {
+    type Item = io::Result<Connection>;
+
+    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+        match self.inner.poll_accept(cx) {
+            Poll::Ready(Ok((connection, _))) => Poll::Ready(Some(Ok(Connection::new(connection)))),
+            Poll::Ready(Err(err)) => Poll::Ready(Some(Err(err))),
+            Poll::Pending => Poll::Pending,
+        }
+    }
+}
+
+pin_project! {
+    /// A wrapper around a [tokio_listener::Connection] that implements the [Connected] trait
+    /// so it is compatible with [tonic].
+    pub struct Connection {
+        #[pin]
+        inner: tokio_listener::Connection,
+    }
+}
+
+impl Connection {
+    fn new(inner: tokio_listener::Connection) -> Self {
+        Self { inner }
+    }
+}
+
+impl Deref for Connection {
+    type Target = tokio_listener::Connection;
+
+    fn deref(&self) -> &Self::Target {
+        &self.inner
+    }
+}
+
+impl DerefMut for Connection {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut self.inner
+    }
+}
+
+impl Connected for Connection {
+    type ConnectInfo = ();
+
+    fn connect_info(&self) -> Self::ConnectInfo {
+        ()
+    }
+}
+
+impl AsyncRead for Connection {
+    fn poll_read(
+        self: Pin<&mut Self>,
+        cx: &mut std::task::Context<'_>,
+        buf: &mut tokio::io::ReadBuf<'_>,
+    ) -> Poll<io::Result<()>> {
+        self.project().inner.poll_read(cx, buf)
+    }
+}
+
+impl AsyncWrite for Connection {
+    fn poll_write(
+        self: Pin<&mut Self>,
+        cx: &mut std::task::Context<'_>,
+        buf: &[u8],
+    ) -> Poll<std::result::Result<usize, io::Error>> {
+        self.project().inner.poll_write(cx, buf)
+    }
+
+    fn poll_flush(
+        self: Pin<&mut Self>,
+        cx: &mut std::task::Context<'_>,
+    ) -> Poll<std::result::Result<(), io::Error>> {
+        self.project().inner.poll_flush(cx)
+    }
+
+    fn poll_shutdown(
+        self: Pin<&mut Self>,
+        cx: &mut std::task::Context<'_>,
+    ) -> Poll<std::result::Result<(), io::Error>> {
+        self.project().inner.poll_shutdown(cx)
+    }
+}