Try to implement a trait for storage.

This commit is contained in:
Half-Shot 2024-02-09 00:02:05 +00:00
parent 5b87dc046e
commit 4b626ee420
23 changed files with 652 additions and 41 deletions

492
Cargo.lock generated
View File

@ -38,6 +38,161 @@ version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f093eed78becd229346bf859eec0aa4dd7ddde0757287b2b4107a1f09c80002" checksum = "5f093eed78becd229346bf859eec0aa4dd7ddde0757287b2b4107a1f09c80002"
[[package]]
name = "async-channel"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35"
dependencies = [
"concurrent-queue",
"event-listener 2.5.3",
"futures-core",
]
[[package]]
name = "async-channel"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f28243a43d821d11341ab73c80bed182dc015c514b951616cf79bd4af39af0c3"
dependencies = [
"concurrent-queue",
"event-listener 5.0.0",
"event-listener-strategy 0.5.0",
"futures-core",
"pin-project-lite",
]
[[package]]
name = "async-executor"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c"
dependencies = [
"async-lock 3.3.0",
"async-task",
"concurrent-queue",
"fastrand 2.0.1",
"futures-lite 2.2.0",
"slab",
]
[[package]]
name = "async-global-executor"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c"
dependencies = [
"async-channel 2.2.0",
"async-executor",
"async-io 2.3.1",
"async-lock 3.3.0",
"blocking",
"futures-lite 2.2.0",
"once_cell",
]
[[package]]
name = "async-io"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af"
dependencies = [
"async-lock 2.8.0",
"autocfg",
"cfg-if",
"concurrent-queue",
"futures-lite 1.13.0",
"log",
"parking",
"polling 2.8.0",
"rustix 0.37.27",
"slab",
"socket2 0.4.10",
"waker-fn",
]
[[package]]
name = "async-io"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f97ab0c5b00a7cdbe5a371b9a782ee7be1316095885c8a4ea1daf490eb0ef65"
dependencies = [
"async-lock 3.3.0",
"cfg-if",
"concurrent-queue",
"futures-io",
"futures-lite 2.2.0",
"parking",
"polling 3.4.0",
"rustix 0.38.28",
"slab",
"tracing",
"windows-sys 0.52.0",
]
[[package]]
name = "async-lock"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b"
dependencies = [
"event-listener 2.5.3",
]
[[package]]
name = "async-lock"
version = "3.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b"
dependencies = [
"event-listener 4.0.3",
"event-listener-strategy 0.4.0",
"pin-project-lite",
]
[[package]]
name = "async-std"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d"
dependencies = [
"async-channel 1.9.0",
"async-global-executor",
"async-io 1.13.0",
"async-lock 2.8.0",
"crossbeam-utils",
"futures-channel",
"futures-core",
"futures-io",
"futures-lite 1.13.0",
"gloo-timers",
"kv-log-macro",
"log",
"memchr",
"once_cell",
"pin-project-lite",
"pin-utils",
"slab",
"wasm-bindgen-futures",
]
[[package]]
name = "async-task"
version = "4.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799"
[[package]]
name = "async-trait"
version = "0.1.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "531b97fb4cd3dfdce92c35dedbfdc1f0b9d8091c8ca943d6dae340ef5012d514"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.42",
]
[[package]] [[package]]
name = "atom_syndication" name = "atom_syndication"
version = "0.12.2" version = "0.12.2"
@ -51,6 +206,12 @@ dependencies = [
"quick-xml", "quick-xml",
] ]
[[package]]
name = "atomic-waker"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.1.0" version = "1.1.0"
@ -99,6 +260,22 @@ dependencies = [
"generic-array", "generic-array",
] ]
[[package]]
name = "blocking"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118"
dependencies = [
"async-channel 2.2.0",
"async-lock 3.3.0",
"async-task",
"fastrand 2.0.1",
"futures-io",
"futures-lite 2.2.0",
"piper",
"tracing",
]
[[package]] [[package]]
name = "bumpalo" name = "bumpalo"
version = "3.14.0" version = "3.14.0"
@ -141,6 +318,29 @@ dependencies = [
"num-traits", "num-traits",
] ]
[[package]]
name = "combine"
version = "4.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4"
dependencies = [
"bytes",
"futures-core",
"memchr",
"pin-project-lite",
"tokio",
"tokio-util",
]
[[package]]
name = "concurrent-queue"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363"
dependencies = [
"crossbeam-utils",
]
[[package]] [[package]]
name = "contrast" name = "contrast"
version = "0.1.0" version = "0.1.0"
@ -176,6 +376,12 @@ version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
[[package]]
name = "crossbeam-utils"
version = "0.8.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
[[package]] [[package]]
name = "crypto-common" name = "crypto-common"
version = "0.1.6" version = "0.1.6"
@ -306,6 +512,63 @@ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
[[package]]
name = "event-listener"
version = "2.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
[[package]]
name = "event-listener"
version = "4.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e"
dependencies = [
"concurrent-queue",
"parking",
"pin-project-lite",
]
[[package]]
name = "event-listener"
version = "5.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b72557800024fabbaa2449dd4bf24e37b93702d457a4d4f2b0dd1f0f039f20c1"
dependencies = [
"concurrent-queue",
"parking",
"pin-project-lite",
]
[[package]]
name = "event-listener-strategy"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3"
dependencies = [
"event-listener 4.0.3",
"pin-project-lite",
]
[[package]]
name = "event-listener-strategy"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "feedafcaa9b749175d5ac357452a9d41ea2911da598fde46ce1fe02c37751291"
dependencies = [
"event-listener 5.0.0",
"pin-project-lite",
]
[[package]]
name = "fastrand"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
dependencies = [
"instant",
]
[[package]] [[package]]
name = "fastrand" name = "fastrand"
version = "2.0.1" version = "2.0.1"
@ -367,6 +630,40 @@ version = "0.3.29"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c"
[[package]]
name = "futures-io"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
[[package]]
name = "futures-lite"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce"
dependencies = [
"fastrand 1.9.0",
"futures-core",
"futures-io",
"memchr",
"parking",
"pin-project-lite",
"waker-fn",
]
[[package]]
name = "futures-lite"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "445ba825b27408685aaecefd65178908c36c6e96aaf6d8599419d46e624192ba"
dependencies = [
"fastrand 2.0.1",
"futures-core",
"futures-io",
"parking",
"pin-project-lite",
]
[[package]] [[package]]
name = "futures-sink" name = "futures-sink"
version = "0.3.29" version = "0.3.29"
@ -386,6 +683,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-sink",
"futures-task", "futures-task",
"pin-project-lite", "pin-project-lite",
"pin-utils", "pin-utils",
@ -418,6 +716,18 @@ version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
[[package]]
name = "gloo-timers"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c"
dependencies = [
"futures-channel",
"futures-core",
"js-sys",
"wasm-bindgen",
]
[[package]] [[package]]
name = "h2" name = "h2"
version = "0.3.24" version = "0.3.24"
@ -520,7 +830,7 @@ dependencies = [
"httpdate", "httpdate",
"itoa", "itoa",
"pin-project-lite", "pin-project-lite",
"socket2", "socket2 0.5.5",
"tokio", "tokio",
"tower-service", "tower-service",
"tracing", "tracing",
@ -567,6 +877,26 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "instant"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
dependencies = [
"cfg-if",
]
[[package]]
name = "io-lifetimes"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
dependencies = [
"hermit-abi",
"libc",
"windows-sys 0.48.0",
]
[[package]] [[package]]
name = "ipnet" name = "ipnet"
version = "2.9.0" version = "2.9.0"
@ -606,6 +936,15 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "kv-log-macro"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f"
dependencies = [
"log",
]
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.4.0" version = "1.4.0"
@ -628,6 +967,12 @@ dependencies = [
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
[[package]]
name = "linux-raw-sys"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
[[package]] [[package]]
name = "linux-raw-sys" name = "linux-raw-sys"
version = "0.4.12" version = "0.4.12"
@ -649,6 +994,9 @@ name = "log"
version = "0.4.20" version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
dependencies = [
"value-bag",
]
[[package]] [[package]]
name = "mac" name = "mac"
@ -674,6 +1022,7 @@ dependencies = [
name = "matrix-hookshot" name = "matrix-hookshot"
version = "5.1.2" version = "5.1.2"
dependencies = [ dependencies = [
"async-std",
"atom_syndication", "atom_syndication",
"contrast", "contrast",
"hex", "hex",
@ -682,6 +1031,7 @@ dependencies = [
"napi-build", "napi-build",
"napi-derive", "napi-derive",
"rand", "rand",
"redis",
"reqwest", "reqwest",
"rgb", "rgb",
"rss", "rss",
@ -903,6 +1253,12 @@ dependencies = [
"vcpkg", "vcpkg",
] ]
[[package]]
name = "parking"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae"
[[package]] [[package]]
name = "parking_lot" name = "parking_lot"
version = "0.12.1" version = "0.12.1"
@ -1024,12 +1380,53 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "piper"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4"
dependencies = [
"atomic-waker",
"fastrand 2.0.1",
"futures-io",
]
[[package]] [[package]]
name = "pkg-config" name = "pkg-config"
version = "0.3.28" version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a"
[[package]]
name = "polling"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce"
dependencies = [
"autocfg",
"bitflags 1.3.2",
"cfg-if",
"concurrent-queue",
"libc",
"log",
"pin-project-lite",
"windows-sys 0.48.0",
]
[[package]]
name = "polling"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30054e72317ab98eddd8561db0f6524df3367636884b7b21b703e4b280a84a14"
dependencies = [
"cfg-if",
"concurrent-queue",
"pin-project-lite",
"rustix 0.38.28",
"tracing",
"windows-sys 0.52.0",
]
[[package]] [[package]]
name = "ppv-lite86" name = "ppv-lite86"
version = "0.2.17" version = "0.2.17"
@ -1110,6 +1507,27 @@ dependencies = [
"getrandom", "getrandom",
] ]
[[package]]
name = "redis"
version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c580d9cbbe1d1b479e8d67cf9daf6a62c957e6846048408b80b43ac3f6af84cd"
dependencies = [
"async-trait",
"bytes",
"combine",
"futures-util",
"itoa",
"percent-encoding",
"pin-project-lite",
"ryu",
"sha1_smol",
"socket2 0.4.10",
"tokio",
"tokio-util",
"url",
]
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.4.1" version = "0.4.1"
@ -1315,6 +1733,20 @@ version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]]
name = "rustix"
version = "0.37.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2"
dependencies = [
"bitflags 1.3.2",
"errno",
"io-lifetimes",
"libc",
"linux-raw-sys 0.3.8",
"windows-sys 0.48.0",
]
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "0.38.28" version = "0.38.28"
@ -1324,7 +1756,7 @@ dependencies = [
"bitflags 2.4.1", "bitflags 2.4.1",
"errno", "errno",
"libc", "libc",
"linux-raw-sys", "linux-raw-sys 0.4.12",
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
@ -1443,6 +1875,12 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "sha1_smol"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012"
[[package]] [[package]]
name = "siphasher" name = "siphasher"
version = "0.3.11" version = "0.3.11"
@ -1464,6 +1902,16 @@ version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
[[package]]
name = "socket2"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d"
dependencies = [
"libc",
"winapi",
]
[[package]] [[package]]
name = "socket2" name = "socket2"
version = "0.5.5" version = "0.5.5"
@ -1556,9 +2004,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"fastrand", "fastrand 2.0.1",
"redox_syscall", "redox_syscall",
"rustix", "rustix 0.38.28",
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
@ -1620,7 +2068,7 @@ dependencies = [
"mio", "mio",
"num_cpus", "num_cpus",
"pin-project-lite", "pin-project-lite",
"socket2", "socket2 0.5.5",
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
@ -1784,6 +2232,12 @@ dependencies = [
"getrandom", "getrandom",
] ]
[[package]]
name = "value-bag"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "126e423afe2dd9ac52142e7e9d5ce4135d7e13776c529d27fd6bc49f19e3280b"
[[package]] [[package]]
name = "vcpkg" name = "vcpkg"
version = "0.2.15" version = "0.2.15"
@ -1796,6 +2250,12 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "waker-fn"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690"
[[package]] [[package]]
name = "want" name = "want"
version = "0.3.1" version = "0.3.1"
@ -1893,6 +2353,28 @@ version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffa44a4268d649eba546544ed45fd9591059d9653a0e584efe030b56d8172b58" checksum = "ffa44a4268d649eba546544ed45fd9591059d9653a0e584efe030b56d8172b58"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.48.0" version = "0.48.0"

View File

@ -23,6 +23,8 @@ ruma = { version = "0.9", features = ["events", "html"] }
reqwest = "0.11" reqwest = "0.11"
rand = "0.8.5" rand = "0.8.5"
uuid = { version = "1.7.0", features = ["v4"] } uuid = { version = "1.7.0", features = ["v4"] }
async-std = "1.12.0"
redis = { version = "0.24.0", features = ["aio", "tokio-comp"] }
[build-dependencies] [build-dependencies]
napi-build = "2" napi-build = "2"

View File

@ -5,7 +5,7 @@ import { Logger } from "matrix-appservice-bridge";
import { LogService, MatrixClient } from "matrix-bot-sdk"; import { LogService, MatrixClient } from "matrix-bot-sdk";
import { getAppservice } from "../appservice"; import { getAppservice } from "../appservice";
import BotUsersManager from "../Managers/BotUsersManager"; import BotUsersManager from "../Managers/BotUsersManager";
import { IBridgeStorageProvider } from "../Stores/StorageProvider"; import { IBridgeStorageProvider } from "../stores/StorageProvider";
const log = new Logger("ResetCryptoStore"); const log = new Logger("ResetCryptoStore");

View File

@ -8,7 +8,7 @@ import { CommentProcessor } from "./CommentProcessor";
import { ConnectionManager } from "./ConnectionManager"; import { ConnectionManager } from "./ConnectionManager";
import { GetIssueResponse, GetIssueOpts } from "./Gitlab/Types" import { GetIssueResponse, GetIssueOpts } from "./Gitlab/Types"
import { GithubInstance } from "./github/GithubInstance"; import { GithubInstance } from "./github/GithubInstance";
import { IBridgeStorageProvider } from "./Stores/StorageProvider"; import { IBridgeStorageProvider } from "./stores/StorageProvider";
import { IConnection, GitHubDiscussionSpace, GitHubDiscussionConnection, GitHubUserSpace, JiraProjectConnection, GitLabRepoConnection, import { IConnection, GitHubDiscussionSpace, GitHubDiscussionConnection, GitHubUserSpace, JiraProjectConnection, GitLabRepoConnection,
GitHubIssueConnection, GitHubProjectConnection, GitHubRepoConnection, GitLabIssueConnection, FigmaFileConnection, FeedConnection, GenericHookConnection, WebhookResponse } from "./Connections"; GitHubIssueConnection, GitHubProjectConnection, GitHubRepoConnection, GitLabIssueConnection, FigmaFileConnection, FeedConnection, GenericHookConnection, WebhookResponse } from "./Connections";
import { IGitLabWebhookIssueStateEvent, IGitLabWebhookMREvent, IGitLabWebhookNoteEvent, IGitLabWebhookPushEvent, IGitLabWebhookReleaseEvent, IGitLabWebhookTagPushEvent, IGitLabWebhookWikiPageEvent } from "./Gitlab/WebhookTypes"; import { IGitLabWebhookIssueStateEvent, IGitLabWebhookMREvent, IGitLabWebhookNoteEvent, IGitLabWebhookPushEvent, IGitLabWebhookReleaseEvent, IGitLabWebhookTagPushEvent, IGitLabWebhookWikiPageEvent } from "./Gitlab/WebhookTypes";

View File

@ -13,7 +13,7 @@ import { FigmaFileConnection, FeedConnection } from "./Connections";
import { GetConnectionTypeResponseItem } from "./provisioning/api"; import { GetConnectionTypeResponseItem } from "./provisioning/api";
import { GitLabClient } from "./Gitlab/Client"; import { GitLabClient } from "./Gitlab/Client";
import { GithubInstance } from "./github/GithubInstance"; import { GithubInstance } from "./github/GithubInstance";
import { IBridgeStorageProvider } from "./Stores/StorageProvider"; import { IBridgeStorageProvider } from "./stores/StorageProvider";
import { JiraProject, JiraVersion } from "./jira/Types"; import { JiraProject, JiraVersion } from "./jira/Types";
import { Logger } from "matrix-appservice-bridge"; import { Logger } from "matrix-appservice-bridge";
import { MessageSenderClient } from "./MatrixSender"; import { MessageSenderClient } from "./MatrixSender";

View File

@ -4,7 +4,7 @@ import { FigmaPayload } from "../figma/types";
import { BaseConnection } from "./BaseConnection"; import { BaseConnection } from "./BaseConnection";
import { IConnection, IConnectionState } from "."; import { IConnection, IConnectionState } from ".";
import { Logger } from "matrix-appservice-bridge"; import { Logger } from "matrix-appservice-bridge";
import { IBridgeStorageProvider } from "../Stores/StorageProvider"; import { IBridgeStorageProvider } from "../stores/StorageProvider";
import { BridgeConfig } from "../config/Config"; import { BridgeConfig } from "../config/Config";
import { Connection, InstantiateConnectionOpts, ProvisionConnectionOpts } from "./IConnection"; import { Connection, InstantiateConnectionOpts, ProvisionConnectionOpts } from "./IConnection";
import { ConfigGrantChecker, GrantChecker } from "../grants/GrantCheck"; import { ConfigGrantChecker, GrantChecker } from "../grants/GrantCheck";

View File

@ -16,7 +16,7 @@ import { CommandError } from "../errors";
import QuickLRU from "@alloc/quick-lru"; import QuickLRU from "@alloc/quick-lru";
import { HookFilter } from "../HookFilter"; import { HookFilter } from "../HookFilter";
import { GitLabClient } from "../Gitlab/Client"; import { GitLabClient } from "../Gitlab/Client";
import { IBridgeStorageProvider } from "../Stores/StorageProvider"; import { IBridgeStorageProvider } from "../stores/StorageProvider";
import axios from "axios"; import axios from "axios";
import { GitLabGrantChecker } from "../Gitlab/GrantChecker"; import { GitLabGrantChecker } from "../Gitlab/GrantChecker";

View File

@ -6,7 +6,7 @@ import { BridgeConfig, BridgePermissionLevel } from "../config/Config";
import { UserTokenStore } from "../UserTokenStore"; import { UserTokenStore } from "../UserTokenStore";
import { CommentProcessor } from "../CommentProcessor"; import { CommentProcessor } from "../CommentProcessor";
import { MessageSenderClient } from "../MatrixSender"; import { MessageSenderClient } from "../MatrixSender";
import { IBridgeStorageProvider } from "../Stores/StorageProvider"; import { IBridgeStorageProvider } from "../stores/StorageProvider";
import { GithubInstance } from "../github/GithubInstance"; import { GithubInstance } from "../github/GithubInstance";
import "reflect-metadata"; import "reflect-metadata";

View File

@ -1,5 +1,5 @@
import { MessageSenderClient } from "./MatrixSender"; import { MessageSenderClient } from "./MatrixSender";
import { IBridgeStorageProvider } from "./Stores/StorageProvider"; import { IBridgeStorageProvider } from "./stores/StorageProvider";
import { UserNotificationsEvent } from "./Notifications/UserNotificationWatcher"; import { UserNotificationsEvent } from "./Notifications/UserNotificationWatcher";
import { Logger } from "matrix-appservice-bridge"; import { Logger } from "matrix-appservice-bridge";
import { AdminRoom } from "./AdminRoom"; import { AdminRoom } from "./AdminRoom";

View File

@ -5,7 +5,7 @@ import { ApiError, ErrCode } from "../api";
import { BridgeConfig } from "../config/Config"; import { BridgeConfig } from "../config/Config";
import { GetAuthPollResponse, GetAuthResponse, GetConnectionsForServiceResponse } from "./BridgeWidgetInterface"; import { GetAuthPollResponse, GetAuthResponse, GetConnectionsForServiceResponse } from "./BridgeWidgetInterface";
import { ProvisioningApi, ProvisioningRequest } from "matrix-appservice-bridge"; import { ProvisioningApi, ProvisioningRequest } from "matrix-appservice-bridge";
import { IBridgeStorageProvider } from "../Stores/StorageProvider"; import { IBridgeStorageProvider } from "../stores/StorageProvider";
import { ConnectionManager } from "../ConnectionManager"; import { ConnectionManager } from "../ConnectionManager";
import BotUsersManager, {BotUser} from "../Managers/BotUsersManager"; import BotUsersManager, {BotUser} from "../Managers/BotUsersManager";
import { assertUserPermissionsInRoom, GetConnectionsResponseItem } from "../provisioning/api"; import { assertUserPermissionsInRoom, GetConnectionsResponseItem } from "../provisioning/api";

View File

@ -2,9 +2,9 @@ import { Logger } from "matrix-appservice-bridge";
import { Appservice, IAppserviceCryptoStorageProvider, IAppserviceRegistration, RustSdkAppserviceCryptoStorageProvider, RustSdkCryptoStoreType } from "matrix-bot-sdk"; import { Appservice, IAppserviceCryptoStorageProvider, IAppserviceRegistration, RustSdkAppserviceCryptoStorageProvider, RustSdkCryptoStoreType } from "matrix-bot-sdk";
import { BridgeConfig } from "./config/Config"; import { BridgeConfig } from "./config/Config";
import Metrics from "./Metrics"; import Metrics from "./Metrics";
import { MemoryStorageProvider } from "./Stores/MemoryStorageProvider"; import { MemoryStorageProvider } from "./stores/MemoryStorageProvider";
import { RedisStorageProvider } from "./Stores/RedisStorageProvider"; import { RedisStorageProvider } from "./stores/RedisStorageProvider";
import { IBridgeStorageProvider } from "./Stores/StorageProvider"; import { IBridgeStorageProvider } from "./stores/StorageProvider";
const log = new Logger("Appservice"); const log = new Logger("Appservice");
export function getAppservice(config: BridgeConfig, registration: IAppserviceRegistration) { export function getAppservice(config: BridgeConfig, registration: IAppserviceRegistration) {

View File

@ -7,7 +7,7 @@ import axios from "axios";
import Metrics from "../Metrics"; import Metrics from "../Metrics";
import { randomUUID } from "crypto"; import { randomUUID } from "crypto";
import { readFeed } from "../libRs"; import { readFeed } from "../libRs";
import { IBridgeStorageProvider } from "../Stores/StorageProvider"; import { IBridgeStorageProvider } from "../stores/StorageProvider";
import UserAgent from "../UserAgent"; import UserAgent from "../UserAgent";
import { QueueWithBackoff } from "../libRs"; import { QueueWithBackoff } from "../libRs";

View File

@ -1,14 +1,37 @@
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use crate::util::QueueWithBackoff; use crate::util::QueueWithBackoff;
use std::time::Instant; use std::time::{Duration, Instant};
use napi::bindgen_prelude::{Error as JsError, Status}; use napi::bindgen_prelude::{Error as JsError, Status};
use napi::tokio::sync::RwLock;
use std::sync::Arc;
use uuid::Uuid; use uuid::Uuid;
use crate::feeds::parser::{js_read_feed, ReadFeedOptions}; use crate::feeds::parser::{js_read_feed, ReadFeedOptions};
use crate::stores::memory::MemoryStorageProvider;
use crate::stores::traits::StorageProvider;
const BACKOFF_TIME_MAX_MS: f64 = 24f64 * 60f64 * 60f64 * 1000f64; const BACKOFF_TIME_MAX_MS: f64 = 24f64 * 60f64 * 60f64 * 1000f64;
const BACKOFF_POW: f64 = 1.05f64; const BACKOFF_POW: f64 = 1.05f64;
const BACKOFF_TIME_MS: f64 = 5f64 * 1000f64; const BACKOFF_TIME_MS: f64 = 5f64 * 1000f64;
#[derive(Serialize, Debug, Deserialize)]
#[napi(object)]
struct HookshotFeedInfo {
pub title: String,
pub url: String,
pub entries: Vec<HookshotFeedEntry>,
pub fetch_key: String,
}
#[derive(Serialize, Debug, Deserialize)]
#[napi(object)]
struct HookshotFeedEntry {
pub title: Option<String>,
pub pubdate: Option<String>,
pub summary: Option<String>,
pub author: Option<String>,
pub link: Option<String>,
}
struct CacheTime { struct CacheTime {
etag: Option<String>, etag: Option<String>,
last_modified: Option<String>, last_modified: Option<String>,
@ -24,17 +47,16 @@ impl CacheTime {
} }
#[napi] #[napi]
pub struct FeedReader { pub struct FeedReader {
queue: QueueWithBackoff, queue: QueueWithBackoff,
feeds_to_retain: HashSet<String>, feeds_to_retain: HashSet<String>,
cache_times: HashMap<String, CacheTime>, cache_times: Arc<RwLock<HashMap<String, CacheTime>>>,
storage_provider: Box<impl StorageProvider>,
poll_interval_seconds: f64, poll_interval_seconds: f64,
poll_concurrency: u8, poll_concurrency: u8,
poll_timeout_seconds: i64, poll_timeout_seconds: i64,
} }
#[napi] #[napi]
pub struct FeedReaderMetrics { pub struct FeedReaderMetrics {
feeds_failing_http: usize, feeds_failing_http: usize,
@ -46,17 +68,21 @@ pub struct FeedReaderMetrics {
impl FeedReader { impl FeedReader {
#[napi(constructor)] #[napi(constructor)]
pub fn new(poll_interval_seconds: f64, poll_concurrency: u8, poll_timeout_seconds: i64) -> Self { pub fn new(poll_interval_seconds: f64, poll_concurrency: u8, poll_timeout_seconds: i64) -> Self {
let mut cache_times: HashMap<String, CacheTime> = HashMap::new();
let mut lock = Arc::new(RwLock::new(cache_times));
let mut storage_provider = MemoryStorageProvider::new();
FeedReader { FeedReader {
queue: QueueWithBackoff::new( queue: QueueWithBackoff::new(
BACKOFF_TIME_MS, BACKOFF_TIME_MS,
BACKOFF_POW, BACKOFF_POW,
BACKOFF_TIME_MAX_MS, BACKOFF_TIME_MAX_MS,
), ),
storage_provider,
feeds_to_retain: HashSet::new(), feeds_to_retain: HashSet::new(),
cache_times: HashMap::new(),
poll_interval_seconds, poll_interval_seconds,
poll_concurrency, poll_concurrency,
poll_timeout_seconds, poll_timeout_seconds,
cache_times: lock,
} }
} }
@ -68,38 +94,56 @@ impl FeedReader {
} }
} }
#[napi]
pub fn on_new_url(&mut self, url: String) { pub fn on_new_url(&mut self, url: String) {
self.queue.push(url); self.queue.push(url);
} }
#[napi]
pub fn on_removed_url(&mut self) { pub fn on_removed_url(&mut self) {
} }
async fn poll_feed(&mut self, url: &String) -> Result<bool, JsError> { async fn poll_feed(&self, url: &String, cache_times: Arc<RwLock<HashMap<String, CacheTime>>>) -> Result<Option<HookshotFeedInfo>, JsError> {
self.feeds_to_retain.insert(url.clone());
let seen_entries_changed = false; let seen_entries_changed = false;
let fetch_key = Uuid::new_v4().to_string(); let fetch_key = Uuid::new_v4().to_string();
let cache_time = self.cache_times.get(url);
let c_t = cache_times.read().await;
let cache_time = c_t.get(url);
let etag = cache_time.and_then(|c| c.etag.clone()).or(None);
let last_modified = cache_time.and_then(|c| c.last_modified.clone()).or(None);
drop(c_t);
if let Ok(result) = js_read_feed(url.clone(), ReadFeedOptions { if let Ok(result) = js_read_feed(url.clone(), ReadFeedOptions {
poll_timeout_seconds: self.poll_timeout_seconds, poll_timeout_seconds: self.poll_timeout_seconds,
etag: cache_time.and_then(|c| c.etag.clone()).or(None), etag,
last_modified: cache_time.and_then(|c| c.last_modified.clone()).or(None), last_modified,
user_agent: "faked user agent".to_string(), user_agent: "faked user agent".to_string(),
}).await { }).await {
self.cache_times.insert(url.clone(), CacheTime { let mut c_t_w = cache_times.write().await;
c_t_w.insert(url.clone(), CacheTime {
etag: result.etag, etag: result.etag,
last_modified: result.last_modified, last_modified: result.last_modified,
}); });
drop(c_t_w);
let initial_sync = false; // TODO: Implement let initial_sync = false; // TODO: Implement
let seen_items: HashSet<String> = HashSet::new(); // TODO: Implement let seen_items: HashSet<String> = HashSet::new(); // TODO: Implement
let mut new_guids: Vec<String> = Vec::new(); let mut new_guids: Vec<String> = Vec::new();
let new_entries: Vec<HookshotFeedEntry> = Vec::new();
if let Some(feed) = result.feed { if let Some(feed) = result.feed {
println!("Got feed result!");
let mut feed_info = HookshotFeedInfo {
title: feed.title,
url: url.clone(),
entries: vec![],
fetch_key,
};
for item in feed.items { for item in feed.items {
println!("Got feed result! {:?}", item);
if let Some(hash_id) = item.hash_id { if let Some(hash_id) = item.hash_id {
if seen_items.contains(&hash_id) { if seen_items.contains(&hash_id) {
continue; continue;
@ -111,16 +155,23 @@ impl FeedReader {
// Skip. // Skip.
continue; continue;
} }
feed_info.entries.push(HookshotFeedEntry {
title: item.title,
pubdate: item.pubdate,
summary: item.summary,
author: item.author,
link: item.link,
});
} }
} }
return Ok(Some(feed_info));
} else { } else {
// TODO: Implement // TODO: Implement
} }
} // TODO: Handle error. } // TODO: Handle error.
Ok(true) Ok(None)
} }
fn sleeping_interval(&self) -> f64 { fn sleeping_interval(&self) -> f64 {
@ -128,17 +179,19 @@ impl FeedReader {
} }
#[napi] #[napi]
pub async unsafe fn poll_feeds(&mut self) -> Result<f64, JsError> { pub async unsafe fn poll_feeds(&mut self) -> Result<(), JsError> {
let now = Instant::now(); let mut sleep_for = self.sleeping_interval();
if let Some(url) = self.queue.pop() { if let Some(url) = self.queue.pop() {
self.poll_feed(&url).await?; self.feeds_to_retain.insert(url.clone());
let now = Instant::now();
let result = self.poll_feed(&url, self.cache_times.clone()).await?;
self.feeds_to_retain.remove(&url);
let elapsed = now.elapsed(); let elapsed = now.elapsed();
let sleepFor = (self.sleeping_interval() - (elapsed.as_millis() as f64)).max(0.0); sleep_for = (sleep_for - (elapsed.as_millis() as f64)).max(0.0);
return Ok(sleepFor);
} else { } else {
println!("No feeds available");
} }
return Ok(self.sleeping_interval()); async_std::task::sleep(Duration::from_millis(sleep_for as u64)).await;
Ok(())
} }
} }

View File

@ -5,6 +5,8 @@ pub mod github;
pub mod jira; pub mod jira;
pub mod util; pub mod util;
mod stores;
#[macro_use] #[macro_use]
extern crate napi_derive; extern crate napi_derive;

44
src/stores/memory.rs Normal file
View File

@ -0,0 +1,44 @@
use std::collections::{HashMap, HashSet};
use crate::stores::traits::StorageProvider;
pub struct MemoryStorageProvider {
guids: HashMap<String, HashSet<String>>,
}
impl MemoryStorageProvider {
pub fn new() -> Self {
MemoryStorageProvider {
guids: HashMap::new(),
}
}
}
impl StorageProvider for MemoryStorageProvider {
async fn store_feed_guids(&mut self, url: &String, guids: &Vec<String>) -> Result<(), Err<String>> {
let mut guid_set = self.guids.get(url).or_else(|| {
let new = HashSet::new();
self.guids.insert(url.clone(), new);
Some(&new)
}).unwrap();
for guid in guids {
guid_set.insert(guid.clone());
}
Ok(())
}
async fn has_seen_feed(&self, url: &String, guids: &Vec<String>) -> Result<bool, Err<String>> {
Ok(self.guids.contains_key(url))
}
async fn has_seen_feed_guids(&self,url: &String, guids: &Vec<String>) -> Result<Vec<String>, Err<String>> {
let mut seen_guids = Vec::default();
if let Some(existing_guids) = self.guids.get(url) {
for guid in guids {
if existing_guids.contains(guid) {
seen_guids.push(guid.clone());
}
}
}
Ok(seen_guids)
}
}

3
src/stores/mod.rs Normal file
View File

@ -0,0 +1,3 @@
pub mod traits;
// pub mod redis;
pub mod memory;

20
src/stores/redis.rs Normal file
View File

@ -0,0 +1,20 @@
use redis::{Commands, ConnectionInfo};
use crate::stores::traits::StorageProvider;
pub struct RedisStorageProvider {
client: redis::Client,
}
impl RedisStorageProvider {
pub fn new(self, host: String, port: u16) -> Self {
let client = redis::Client::open((host, port))?;
RedisStorageProvider {
client,
}
}
}
impl StorageProvider for RedisStorageProvider {
}

5
src/stores/traits.rs Normal file
View File

@ -0,0 +1,5 @@
trait StorageProvider {
async fn store_feed_guids(&mut self, url: &String, guids: &Vec<String>) -> Result<Ok, Err<String>>;
async fn has_seen_feed(&self, url: &String, guids: &Vec<String>) -> Result<bool, Err<String>>;
async fn has_seen_feed_guids(&self, url: &String, guids: &Vec<String>) -> Result<Vec<String>, Err<String>>;
}

View File

@ -5,7 +5,7 @@ import { ConnectionManager } from "../src/ConnectionManager";
import { IConnection } from "../src/Connections"; import { IConnection } from "../src/Connections";
import { FeedEntry, FeedReader } from "../src/feeds/FeedReader"; import { FeedEntry, FeedReader } from "../src/feeds/FeedReader";
import { MessageQueue, MessageQueueMessage } from "../src/MessageQueue"; import { MessageQueue, MessageQueueMessage } from "../src/MessageQueue";
import { MemoryStorageProvider } from "../src/Stores/MemoryStorageProvider"; import { MemoryStorageProvider } from "../src/stores/MemoryStorageProvider";
import { Server, createServer } from 'http'; import { Server, createServer } from 'http';
import { AddressInfo } from "net"; import { AddressInfo } from "net";

View File

@ -5,7 +5,7 @@ import { ApiError, ErrCode, ValidatorApiError } from "../../src/api";
import { GitLabRepoConnection, GitLabRepoConnectionState } from "../../src/Connections"; import { GitLabRepoConnection, GitLabRepoConnectionState } from "../../src/Connections";
import { expect } from "chai"; import { expect } from "chai";
import { BridgeConfigGitLab } from "../../src/config/Config"; import { BridgeConfigGitLab } from "../../src/config/Config";
import { IBridgeStorageProvider } from "../../src/Stores/StorageProvider"; import { IBridgeStorageProvider } from "../../src/stores/StorageProvider";
import { IntentMock } from "../utils/IntentMock"; import { IntentMock } from "../utils/IntentMock";
const ROOM_ID = "!foo:bar"; const ROOM_ID = "!foo:bar";