Compare commits

...
2 Commits
Author SHA1 Message Date
Ultradesu 63506e3af2 Aupdated FRID to v4 protocol
Build and Publish / Build and Publish Docker Image (push) Successful in 5m4s
2026-07-23 15:52:42 +03:00
Ultradesu 5b339aa921 Fixed content_id persistence
Build and Publish / Build and Publish Docker Image (push) Successful in 7m30s
2026-07-20 18:40:32 +03:00
5 changed files with 182 additions and 184 deletions
Generated
+73 -117
View File
@@ -23,8 +23,8 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0"
dependencies = [ dependencies = [
"crypto-common 0.1.7", "crypto-common 0.1.6",
"generic-array 0.14.7", "generic-array 0.14.9",
] ]
[[package]] [[package]]
@@ -290,7 +290,7 @@ checksum = "ae36dc4177970ef04fde5178d3e2429882def40e57a451f919c098f72baa6cec"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 3.0.2", "syn 3.0.3",
] ]
[[package]] [[package]]
@@ -544,7 +544,7 @@ version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [ dependencies = [
"generic-array 0.14.7", "generic-array 0.14.9",
] ]
[[package]] [[package]]
@@ -684,15 +684,15 @@ version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
dependencies = [ dependencies = [
"crypto-common 0.1.7", "crypto-common 0.1.6",
"inout", "inout",
] ]
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.6.3" version = "4.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fb99565819980999fb7b4a1796046a5c949e6d4ff132cf5fadf5a641e20d776" checksum = "d91e0c145792ef73a6ad36d27c75ac09f1832222a3c209689d90f534685ee5b7"
dependencies = [ dependencies = [
"clap_builder", "clap_builder",
"clap_derive", "clap_derive",
@@ -712,14 +712,14 @@ dependencies = [
[[package]] [[package]]
name = "clap_derive" name = "clap_derive"
version = "4.6.3" version = "4.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32f2392eae7f16557a3d727ef3a12e57b2b2ca6f98566a5f4fb41ffe305df077" checksum = "d012d2b9d65aca7f18f4d9878a045bc17899bba951561ba5ec3c2ba1eed9a061"
dependencies = [ dependencies = [
"heck", "heck",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.119", "syn 3.0.3",
] ]
[[package]] [[package]]
@@ -1108,7 +1108,7 @@ version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76"
dependencies = [ dependencies = [
"generic-array 0.14.7", "generic-array 0.14.9",
"rand_core 0.6.4", "rand_core 0.6.4",
"subtle", "subtle",
"zeroize", "zeroize",
@@ -1116,11 +1116,11 @@ dependencies = [
[[package]] [[package]]
name = "crypto-common" name = "crypto-common"
version = "0.1.7" version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [ dependencies = [
"generic-array 0.14.7", "generic-array 0.14.9",
"typenum", "typenum",
] ]
@@ -1131,6 +1131,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453"
dependencies = [ dependencies = [
"hybrid-array", "hybrid-array",
"rand_core 0.10.1",
] ]
[[package]] [[package]]
@@ -1181,9 +1182,9 @@ dependencies = [
[[package]] [[package]]
name = "curve25519-dalek" name = "curve25519-dalek"
version = "5.0.0-rc.0" version = "5.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f359e08ca85e7bd759e1fd933ff2bccd81864c60a8fba0e259c7f822b0924bf" checksum = "b5eed333089e2e1c1ac8c6c0398e5e2497b4c9926ca6d0365ed1e099afa5bc23"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cpufeatures 0.3.0", "cpufeatures 0.3.0",
@@ -1417,7 +1418,7 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [ dependencies = [
"block-buffer 0.10.4", "block-buffer 0.10.4",
"const-oid 0.9.6", "const-oid 0.9.6",
"crypto-common 0.1.7", "crypto-common 0.1.6",
"subtle", "subtle",
] ]
@@ -1558,11 +1559,11 @@ dependencies = [
[[package]] [[package]]
name = "ed25519-dalek" name = "ed25519-dalek"
version = "3.0.0-rc.0" version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b011170fe4f04665565b4110afef66774fe9ffff278f3eb5b81cc73d26e27d60" checksum = "6ebaa1a2bf1290ab3bfe5a7b771d050ebffab2711c19a81691c683a5144a25de"
dependencies = [ dependencies = [
"curve25519-dalek 5.0.0-rc.0", "curve25519-dalek 5.0.0",
"ed25519 3.0.0", "ed25519 3.0.0",
"rand_core 0.10.1", "rand_core 0.10.1",
"serde", "serde",
@@ -1591,7 +1592,7 @@ dependencies = [
"crypto-bigint", "crypto-bigint",
"digest 0.10.7", "digest 0.10.7",
"ff", "ff",
"generic-array 0.14.7", "generic-array 0.14.9",
"group", "group",
"hkdf", "hkdf",
"pem-rfc7468 0.7.0", "pem-rfc7468 0.7.0",
@@ -1717,7 +1718,7 @@ dependencies = [
[[package]] [[package]]
name = "federation-net" name = "federation-net"
version = "0.1.0" version = "0.1.0"
source = "git+https://gt.hexor.cy/ab/frid.git#8ee1db9cf89ea604c6b8a8c3fe089a714c1e321f" source = "git+https://gt.hexor.cy/ab/frid.git#aaaad780f2bc3f4ba42bd3eef6aca871a2ff68da"
dependencies = [ dependencies = [
"blake3", "blake3",
"data-encoding", "data-encoding",
@@ -1844,7 +1845,7 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
[[package]] [[package]]
name = "furumusic" name = "furumusic"
version = "0.6.4-fd" version = "0.6.7-fd"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@@ -2033,9 +2034,9 @@ dependencies = [
[[package]] [[package]]
name = "generic-array" name = "generic-array"
version = "0.14.7" version = "0.14.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2"
dependencies = [ dependencies = [
"typenum", "typenum",
"version_check", "version_check",
@@ -2775,7 +2776,7 @@ checksum = "bee2c455ca60511a054699102d40ce7153621cb2429558f9eaa600e4499b5984"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 3.0.2", "syn 3.0.3",
] ]
[[package]] [[package]]
@@ -2784,7 +2785,7 @@ version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01"
dependencies = [ dependencies = [
"generic-array 0.14.7", "generic-array 0.14.9",
] ]
[[package]] [[package]]
@@ -2829,9 +2830,9 @@ dependencies = [
[[package]] [[package]]
name = "iroh" name = "iroh"
version = "1.0.2" version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fca9b4b462c343ff88fc0af4096c186f939b602a0bc08723536ef2c31c93971" checksum = "460de6bc52163b41b1646931f2897e5ab986f0966ade444467fec25024751a72"
dependencies = [ dependencies = [
"backon", "backon",
"blake3", "blake3",
@@ -2840,7 +2841,7 @@ dependencies = [
"ctutils", "ctutils",
"data-encoding", "data-encoding",
"derive_more", "derive_more",
"ed25519-dalek 3.0.0-rc.0", "ed25519-dalek 3.0.0",
"futures-util", "futures-util",
"getrandom 0.4.3", "getrandom 0.4.3",
"hickory-resolver", "hickory-resolver",
@@ -2880,15 +2881,15 @@ dependencies = [
[[package]] [[package]]
name = "iroh-base" name = "iroh-base"
version = "1.0.2" version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830a582cd54410dc1aa71d4786a82c3297d7b0165accd8b6dbbb3b240b48140d" checksum = "6be73e16ee21c923aca9b3121aaa0db936f7c7ecc156ff47b8dac944c68d59a8"
dependencies = [ dependencies = [
"curve25519-dalek 5.0.0-rc.0", "curve25519-dalek 5.0.0",
"data-encoding", "data-encoding",
"data-encoding-macro", "data-encoding-macro",
"derive_more", "derive_more",
"ed25519-dalek 3.0.0-rc.0", "ed25519-dalek 3.0.0",
"getrandom 0.4.3", "getrandom 0.4.3",
"n0-error", "n0-error",
"rand 0.10.2", "rand 0.10.2",
@@ -2899,9 +2900,9 @@ dependencies = [
[[package]] [[package]]
name = "iroh-dns" name = "iroh-dns"
version = "1.0.2" version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "516e4eedc38e33ab69a6bd325520332dc3d67b25454e2d590ebb84a25240dd9a" checksum = "46f6a9b39d18e6345f5c151afd299f2488e2cb5c520fe41b107b6bd3dc4c3349"
dependencies = [ dependencies = [
"arc-swap", "arc-swap",
"cfg_aliases", "cfg_aliases",
@@ -2950,9 +2951,9 @@ dependencies = [
[[package]] [[package]]
name = "iroh-relay" name = "iroh-relay"
version = "1.0.2" version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8149bb6a57126225a07d6928846d82dcedfd24ea0f863ef7b2eb475e1d726354" checksum = "24bd586cf927f7b700f56ec3639b53cb5fa901ce284784051ff71092bfbf8193"
dependencies = [ dependencies = [
"blake3", "blake3",
"bytes", "bytes",
@@ -2989,7 +2990,6 @@ dependencies = [
"tokio-websockets", "tokio-websockets",
"tracing", "tracing",
"url", "url",
"vergen-gitcl",
"webpki-roots 1.0.9", "webpki-roots 1.0.9",
"ws_stream_wasm", "ws_stream_wasm",
] ]
@@ -3154,9 +3154,9 @@ dependencies = [
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.186" version = "0.2.189"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
[[package]] [[package]]
name = "libm" name = "libm"
@@ -3485,7 +3485,7 @@ dependencies = [
"crc", "crc",
"document-features", "document-features",
"dyn-clone", "dyn-clone",
"ed25519-dalek 3.0.0-rc.0", "ed25519-dalek 3.0.0",
"flume 0.12.0", "flume 0.12.0",
"futures-lite", "futures-lite",
"getrandom 0.4.3", "getrandom 0.4.3",
@@ -3622,7 +3622,7 @@ dependencies = [
[[package]] [[package]]
name = "music-dht" name = "music-dht"
version = "0.1.0" version = "0.1.0"
source = "git+https://gt.hexor.cy/ab/frid.git#8ee1db9cf89ea604c6b8a8c3fe089a714c1e321f" source = "git+https://gt.hexor.cy/ab/frid.git#aaaad780f2bc3f4ba42bd3eef6aca871a2ff68da"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"blake3", "blake3",
@@ -3847,9 +3847,9 @@ checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21"
[[package]] [[package]]
name = "noq" name = "noq"
version = "1.0.1" version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bf95190af1bd4a00a10e8255ca0c8ddd9e9a9f5e79151d7a7eb6d56aff5dc89" checksum = "e11803df44ac03a30988d61585ea50885d5428e42da944fe1e498799da7886a2"
dependencies = [ dependencies = [
"bytes", "bytes",
"cfg_aliases", "cfg_aliases",
@@ -3869,9 +3869,9 @@ dependencies = [
[[package]] [[package]]
name = "noq-proto" name = "noq-proto"
version = "1.0.1" version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa6c890013591e709a3e45dd53501351b7e27e7ff3c7e9fc3dce43e300e7e9d3" checksum = "334c3c9833f7b2c573cceb9896ddc7aaeb58c8807cbb63211b24d1fe88bf866e"
dependencies = [ dependencies = [
"aes-gcm", "aes-gcm",
"bytes", "bytes",
@@ -3896,9 +3896,9 @@ dependencies = [
[[package]] [[package]]
name = "noq-udp" name = "noq-udp"
version = "1.0.1" version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3137a52df66c20090a889828d1c655f21f52294cba64e5c4fbb04fc83eee7c8e" checksum = "bde7a5d5102f1cff03d482240f0ed20551661f63663620f4b26112ed751165e9"
dependencies = [ dependencies = [
"cfg_aliases", "cfg_aliases",
"libc", "libc",
@@ -4034,15 +4034,6 @@ dependencies = [
"syn 2.0.119", "syn 2.0.119",
] ]
[[package]]
name = "num_threads"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "oauth2" name = "oauth2"
version = "5.0.0" version = "5.0.0"
@@ -4960,7 +4951,7 @@ checksum = "2c9283685feec7d69af75fb0e858d5e7378f33fe4fc699383b2916ab9273e03c"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 3.0.2", "syn 3.0.3",
] ]
[[package]] [[package]]
@@ -5209,9 +5200,9 @@ dependencies = [
[[package]] [[package]]
name = "rustls-pki-types" name = "rustls-pki-types"
version = "1.15.0" version = "1.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "764899a24af3980067ee14bc143654f297b22eaebfe3c7b6b211920a5a59b046" checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96"
dependencies = [ dependencies = [
"web-time", "web-time",
"zeroize", "zeroize",
@@ -5364,7 +5355,7 @@ checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc"
dependencies = [ dependencies = [
"base16ct 0.2.0", "base16ct 0.2.0",
"der 0.7.10", "der 0.7.10",
"generic-array 0.14.7", "generic-array 0.14.9",
"pkcs8 0.10.2", "pkcs8 0.10.2",
"subtle", "subtle",
"zeroize", "zeroize",
@@ -5472,7 +5463,7 @@ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 3.0.2", "syn 3.0.3",
] ]
[[package]] [[package]]
@@ -5672,6 +5663,9 @@ name = "signature"
version = "3.0.0" version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d567dcbaf0049cb8ac2608a76cd95ff9e4412e1899d389ee400918ca7537f5" checksum = "28d567dcbaf0049cb8ac2608a76cd95ff9e4412e1899d389ee400918ca7537f5"
dependencies = [
"rand_core 0.10.1",
]
[[package]] [[package]]
name = "simd-adler32" name = "simd-adler32"
@@ -5914,7 +5908,7 @@ dependencies = [
"futures-core", "futures-core",
"futures-io", "futures-io",
"futures-util", "futures-util",
"generic-array 0.14.7", "generic-array 0.14.9",
"hex 0.4.3", "hex 0.4.3",
"hkdf", "hkdf",
"hmac", "hmac",
@@ -6277,9 +6271,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "3.0.2" version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a207d6d6a2b7fc470b80443726053f18a2481b7e1eee970597051596567987a3" checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -6389,7 +6383,7 @@ checksum = "43cbfe0cf76104d42a574802844187e84a305e531ed54455f11fbde0f10541cd"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 3.0.2", "syn 3.0.3",
] ]
[[package]] [[package]]
@@ -6409,9 +6403,7 @@ checksum = "3e1d5e639ff6bab73cb6885cc7e7b1de96c3f32c68ec55f3952614bec1092244"
dependencies = [ dependencies = [
"deranged", "deranged",
"js-sys", "js-sys",
"libc",
"num-conv", "num-conv",
"num_threads",
"powerfmt", "powerfmt",
"serde_core", "serde_core",
"time-core", "time-core",
@@ -6461,9 +6453,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.53.0" version = "1.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d988bcd52dbe076d3d46903332f58c912b87a2c49b1428419a5845154762ffee" checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed"
dependencies = [ dependencies = [
"bytes", "bytes",
"libc", "libc",
@@ -6536,9 +6528,9 @@ dependencies = [
[[package]] [[package]]
name = "tokio-stream" name = "tokio-stream"
version = "0.1.18" version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" checksum = "a3d06f0b082ba57c26b79407372e57cf2a1e28124f78e9479fe80322cf53420b"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"pin-project-lite", "pin-project-lite",
@@ -6548,14 +6540,15 @@ dependencies = [
[[package]] [[package]]
name = "tokio-util" name = "tokio-util"
version = "0.7.18" version = "0.7.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52"
dependencies = [ dependencies = [
"bytes", "bytes",
"futures-core", "futures-core",
"futures-sink", "futures-sink",
"futures-util", "futures-util",
"libc",
"pin-project-lite", "pin-project-lite",
"tokio", "tokio",
] ]
@@ -6868,7 +6861,7 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea"
dependencies = [ dependencies = [
"crypto-common 0.1.7", "crypto-common 0.1.6",
"subtle", "subtle",
] ]
@@ -6938,43 +6931,6 @@ version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "vergen"
version = "9.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b849a1f6d8639e8de261e81ee0fc881e3e3620db1af9f2e0da015d4382ceaf75"
dependencies = [
"anyhow",
"derive_builder",
"rustversion",
"vergen-lib",
]
[[package]]
name = "vergen-gitcl"
version = "9.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77ff3b5300a085d6bcd8fc96a507f706a28ae3814693236c9b409db71a1d15b9"
dependencies = [
"anyhow",
"derive_builder",
"rustversion",
"time",
"vergen",
"vergen-lib",
]
[[package]]
name = "vergen-lib"
version = "9.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b34a29ba7e9c59e62f229ae1932fb1b8fb8a6fdcc99215a641913f5f5a59a569"
dependencies = [
"anyhow",
"derive_builder",
"rustversion",
]
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.5" version = "0.9.5"
@@ -7647,18 +7603,18 @@ dependencies = [
[[package]] [[package]]
name = "zerocopy" name = "zerocopy"
version = "0.8.54" version = "0.8.55"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7cbbc0a705a0fd05cc3676525980d2bf5a9bc4adac6d6475209a7887cf59d19" checksum = "b5a105cd7b140f6eeec8acff2ea38135d3cab283ada58540f629fe51e46696eb"
dependencies = [ dependencies = [
"zerocopy-derive", "zerocopy-derive",
] ]
[[package]] [[package]]
name = "zerocopy-derive" name = "zerocopy-derive"
version = "0.8.54" version = "0.8.55"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2e817b7b52d0c7358d3246da9d69935ebb18116b2b102b4230dac079b4862f5" checksum = "0fe976fb70c78cd64cccfe3a6fc142244e8a77b70959b30faf9d0ac37ee228eb"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "furumusic" name = "furumusic"
version = "0.6.5-fd" version = "0.6.7-fd"
edition = "2024" edition = "2024"
description = "Reusable web-app boilerplate: auth, OIDC/SSO, admin panel, user management, i18n, PostgreSQL" description = "Reusable web-app boilerplate: auth, OIDC/SSO, admin panel, user management, i18n, PostgreSQL"
+94 -47
View File
@@ -36,9 +36,6 @@ pub use serve::{AUDIO_ALPN, CATALOG_ALPN};
/// How often the published library is re-synchronized with the database. /// How often the published library is re-synchronized with the database.
const SYNC_INTERVAL: Duration = Duration::from_secs(60); const SYNC_INTERVAL: Duration = Duration::from_secs(60);
/// Content IDs are file hashes and can be expensive to warm for large
/// libraries. Keep DHT publishing responsive and let later syncs fill them in.
const MAX_CONTENT_HASH_JOBS_PER_SYNC: usize = 512;
struct Running { struct Running {
service: Arc<MusicDhtService>, service: Arc<MusicDhtService>,
@@ -46,6 +43,12 @@ struct Running {
tasks: Vec<tokio::task::JoinHandle<()>>, tasks: Vec<tokio::task::JoinHandle<()>>,
} }
struct ContentHashJob {
media_file_id: i64,
sha256_hash: String,
file_path: String,
}
pub struct Federation { pub struct Federation {
/// Transport data directory; server-side DHT state and identity live in PostgreSQL. /// Transport data directory; server-side DHT state and identity live in PostgreSQL.
data_dir: PathBuf, data_dir: PathBuf,
@@ -440,31 +443,36 @@ impl Federation {
let tracks = sqlx::query( let tracks = sqlx::query(
"SELECT t.id, t.title, COALESCE(t.year, r.year), t.duration_seconds, "SELECT t.id, t.title, COALESCE(t.year, r.year), t.duration_seconds,
r.title, r.release_type, t.track_number, t.disc_number, r.title, r.release_type, t.track_number, t.disc_number,
t.audio_file_id, m.file_path, m.sha256_hash t.audio_file_id, m.file_path, m.sha256_hash, c.content_id
FROM furumusic__track t FROM furumusic__track t
JOIN furumusic__release r ON r.id = t.release_id JOIN furumusic__release r ON r.id = t.release_id
JOIN furumusic__media_file m ON m.id = t.audio_file_id JOIN furumusic__media_file m ON m.id = t.audio_file_id
LEFT JOIN furumusic__federation_content_id_cache c
ON c.media_file_id = m.id AND c.sha256_hash = m.sha256_hash
WHERE t.is_hidden = false AND r.is_hidden = false", WHERE t.is_hidden = false AND r.is_hidden = false",
) )
.fetch_all(&pool) .fetch_all(&pool)
.await?; .await?;
let storage_dir = lock(&self.storage_dir).clone(); let storage_dir = lock(&self.storage_dir).clone();
let mut hash_jobs_scheduled = 0usize; let mut content_hash_jobs = Vec::new();
for row in &tracks { for row in &tracks {
let id: i64 = row.get(0); let id: i64 = row.get(0);
let duration: f64 = row.get(3); let duration: f64 = row.get(3);
let media_file_id: i64 = row.get(8); let media_file_id: i64 = row.get(8);
let file_path: String = row.get(9); let file_path: String = row.get(9);
let sha256_hash: String = row.get(10); let sha256_hash: String = row.get(10);
let (content_id, scheduled_hash) = self.content_id_for_media( let cached_content_id: Option<String> = row.get(11);
media_file_id, let content_id = cached_content_id
sha256_hash, .or_else(|| self.cached_content_id_for_media(media_file_id, &sha256_hash));
file_path, if content_id.is_none()
&storage_dir, && !storage_dir.trim().is_empty()
hash_jobs_scheduled < MAX_CONTENT_HASH_JOBS_PER_SYNC, && self.mark_content_hash_pending(media_file_id)
); {
if scheduled_hash { content_hash_jobs.push(ContentHashJob {
hash_jobs_scheduled += 1; media_file_id,
sha256_hash,
file_path,
});
} }
specs.push(ItemSpec { specs.push(ItemSpec {
local_key: format!("track:{id}"), local_key: format!("track:{id}"),
@@ -481,52 +489,67 @@ impl Federation {
content_id, content_id,
}); });
} }
self.spawn_content_warmer(pool.clone(), storage_dir, content_hash_jobs);
Ok(specs) Ok(specs)
} }
fn content_id_for_media( fn cached_content_id_for_media(&self, media_file_id: i64, sha256_hash: &str) -> Option<String> {
self: &Arc<Self>,
media_file_id: i64,
sha256_hash: String,
file_path: String,
storage_dir: &str,
schedule_missing: bool,
) -> (Option<String>, bool) {
if storage_dir.trim().is_empty() {
return (None, false);
}
if let Some((cached_hash, content_id)) = lock(&self.content_cache).get(&media_file_id) if let Some((cached_hash, content_id)) = lock(&self.content_cache).get(&media_file_id)
&& cached_hash == &sha256_hash && cached_hash == sha256_hash
{ {
return (Some(content_id.clone()), false); return Some(content_id.clone());
}
if !schedule_missing {
return (None, false);
} }
None
}
{ fn mark_content_hash_pending(&self, media_file_id: i64) -> bool {
let mut pending = lock(&self.content_pending); lock(&self.content_pending).insert(media_file_id)
if !pending.insert(media_file_id) { }
return (None, false);
}
}
let storage_dir = storage_dir.to_string(); fn spawn_content_warmer(
self: &Arc<Self>,
pool: PgPool,
storage_dir: String,
jobs: Vec<ContentHashJob>,
) {
if jobs.is_empty() {
return;
}
let fed = Arc::clone(self); let fed = Arc::clone(self);
tokio::spawn(async move { tokio::spawn(async move {
let content_id = let total = jobs.len();
tokio::task::spawn_blocking(move || audio_content_id(&storage_dir, &file_path)) let mut stored = 0usize;
.await for job in jobs {
.ok() let job_storage_dir = storage_dir.clone();
.flatten(); let job_file_path = job.file_path.clone();
lock(&fed.content_pending).remove(&media_file_id); let content_id = tokio::task::spawn_blocking(move || {
if let Some(content_id) = content_id { audio_content_id(&job_storage_dir, &job_file_path)
lock(&fed.content_cache).insert(media_file_id, (sha256_hash, content_id)); })
.await
.ok()
.flatten();
lock(&fed.content_pending).remove(&job.media_file_id);
if let Some(content_id) = content_id {
lock(&fed.content_cache).insert(
job.media_file_id,
(job.sha256_hash.clone(), content_id.clone()),
);
if let Err(err) =
persist_content_id(&pool, job.media_file_id, &job.sha256_hash, &content_id)
.await
{
tracing::warn!(
media_file_id = job.media_file_id,
"federation content-id cache write failed: {err:#}"
);
} else {
stored += 1;
}
}
} }
tracing::info!(total, stored, "federation content-id cache warm finished");
}); });
(None, true)
} }
/// Live status for the admin page. /// Live status for the admin page.
@@ -586,6 +609,30 @@ impl Federation {
} }
} }
async fn persist_content_id(
pool: &PgPool,
media_file_id: i64,
sha256_hash: &str,
content_id: &str,
) -> Result<()> {
sqlx::query(
"INSERT INTO furumusic__federation_content_id_cache
(media_file_id, sha256_hash, content_id, updated_at)
VALUES ($1, $2, $3, $4)
ON CONFLICT (media_file_id) DO UPDATE SET
sha256_hash = EXCLUDED.sha256_hash,
content_id = EXCLUDED.content_id,
updated_at = EXCLUDED.updated_at",
)
.bind(media_file_id)
.bind(sha256_hash)
.bind(content_id)
.bind(now_iso())
.execute(pool)
.await?;
Ok(())
}
fn audio_content_id(storage_dir: &str, file_path: &str) -> Option<String> { fn audio_content_id(storage_dir: &str, file_path: &str) -> Option<String> {
if storage_dir.trim().is_empty() { if storage_dir.trim().is_empty() {
return None; return None;
+6 -19
View File
@@ -522,7 +522,7 @@ async fn serve_catalog_one(
match request.want.as_deref() { match request.want.as_deref() {
None | Some("catalog") => { None | Some("catalog") => {
let response = match build_catalog(&pool, &own, &storage_dir, &request.artist).await { let response = match build_catalog(&pool, &own, &request.artist).await {
Ok(response) => response, Ok(response) => response,
Err(err) => CatalogResponse { Err(err) => CatalogResponse {
ok: false, ok: false,
@@ -582,12 +582,7 @@ async fn serve_catalog_one(
Ok(()) Ok(())
} }
async fn build_catalog( async fn build_catalog(pool: &PgPool, own: &EndpointId, artist: &str) -> Result<CatalogResponse> {
pool: &PgPool,
own: &EndpointId,
storage_dir: &str,
artist: &str,
) -> Result<CatalogResponse> {
let Some(artist_row) = sqlx::query( let Some(artist_row) = sqlx::query(
"SELECT id, name FROM furumusic__artist "SELECT id, name FROM furumusic__artist
WHERE LOWER(name) = LOWER($1) AND is_hidden = false WHERE LOWER(name) = LOWER($1) AND is_hidden = false
@@ -620,9 +615,11 @@ async fn build_catalog(
let release_id: i64 = release_row.get(0); let release_id: i64 = release_row.get(0);
let track_rows = sqlx::query( let track_rows = sqlx::query(
"SELECT t.id, t.title, t.track_number, t.disc_number, t.duration_seconds, "SELECT t.id, t.title, t.track_number, t.disc_number, t.duration_seconds,
m.file_path c.content_id
FROM furumusic__track t FROM furumusic__track t
JOIN furumusic__media_file m ON m.id = t.audio_file_id JOIN furumusic__media_file m ON m.id = t.audio_file_id
LEFT JOIN furumusic__federation_content_id_cache c
ON c.media_file_id = m.id AND c.sha256_hash = m.sha256_hash
WHERE t.release_id = $1 AND t.is_hidden = false WHERE t.release_id = $1 AND t.is_hidden = false
ORDER BY t.disc_number NULLS FIRST, t.track_number NULLS LAST, t.title", ORDER BY t.disc_number NULLS FIRST, t.track_number NULLS LAST, t.title",
) )
@@ -633,14 +630,12 @@ async fn build_catalog(
for row in track_rows { for row in track_rows {
let track_id: i64 = row.get(0); let track_id: i64 = row.get(0);
let duration: f64 = row.get(4); let duration: f64 = row.get(4);
let file_path: String = row.get(5);
let content_id = catalog_content_id(storage_dir, file_path).await;
tracks.push(CatalogTrack { tracks.push(CatalogTrack {
title: row.get(1), title: row.get(1),
track_number: row.get(2), track_number: row.get(2),
disc_number: row.get(3), disc_number: row.get(3),
duration_seconds: (duration > 0.0).then_some(duration), duration_seconds: (duration > 0.0).then_some(duration),
content_id, content_id: row.get(5),
item_id: item_id_of(own, track_id), item_id: item_id_of(own, track_id),
}); });
} }
@@ -662,14 +657,6 @@ async fn build_catalog(
}) })
} }
async fn catalog_content_id(storage_dir: &str, file_path: String) -> Option<String> {
let storage_dir = storage_dir.to_string();
tokio::task::spawn_blocking(move || super::audio_content_id(&storage_dir, &file_path))
.await
.ok()
.flatten()
}
async fn artist_image_by_name(pool: &PgPool, artist: &str) -> Result<Option<(String, String)>> { async fn artist_image_by_name(pool: &PgPool, artist: &str) -> Result<Option<(String, String)>> {
let row = sqlx::query( let row = sqlx::query(
"SELECT m.file_path, m.mime_type FROM furumusic__artist a "SELECT m.file_path, m.mime_type FROM furumusic__artist a
+8
View File
@@ -44,6 +44,14 @@ const SCHEMA: &[&str] = &[
ticket TEXT NOT NULL, ticket TEXT NOT NULL,
last_seen_ms BIGINT NOT NULL last_seen_ms BIGINT NOT NULL
)", )",
"CREATE TABLE IF NOT EXISTS furumusic__federation_content_id_cache (
media_file_id BIGINT PRIMARY KEY,
sha256_hash TEXT NOT NULL,
content_id TEXT NOT NULL,
updated_at TEXT NOT NULL
)",
"CREATE INDEX IF NOT EXISTS idx_furumusic_federation_content_id_cache_content_id
ON furumusic__federation_content_id_cache(content_id)",
]; ];
#[derive(Debug, Clone)] #[derive(Debug, Clone)]