rework
This commit is contained in:
parent
1f2e3e6eab
commit
5c3a9a1888
11 changed files with 950 additions and 253 deletions
0
.env
Normal file
0
.env
Normal file
620
Cargo.lock
generated
620
Cargo.lock
generated
|
@ -12,6 +12,17 @@ dependencies = [
|
||||||
"regex",
|
"regex",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ahash"
|
||||||
|
version = "0.7.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
"once_cell",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "0.7.20"
|
version = "0.7.20"
|
||||||
|
@ -21,6 +32,15 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "android_system_properties"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "api"
|
name = "api"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -32,6 +52,7 @@ dependencies = [
|
||||||
"redis",
|
"redis",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"sqlx",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tower-http",
|
"tower-http",
|
||||||
]
|
]
|
||||||
|
@ -163,6 +184,21 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async_once"
|
||||||
|
version = "0.2.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2ce4f10ea3abcd6617873bae9f91d1c5332b4a778bd9ce34d0cd517474c1de82"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atoi"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
@ -171,9 +207,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "axum"
|
name = "axum"
|
||||||
version = "0.6.0"
|
version = "0.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "744864363a200a5e724a7e61bc8c11b6628cf2e3ec519c8a1a48e609a8156b40"
|
checksum = "08b108ad2665fa3f6e6a517c3d80ec3e77d224c47d605167aefaa5d7ef97fa48"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"axum-core",
|
"axum-core",
|
||||||
|
@ -199,7 +235,7 @@ dependencies = [
|
||||||
"sha-1",
|
"sha-1",
|
||||||
"sync_wrapper",
|
"sync_wrapper",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-tungstenite",
|
"tokio-tungstenite 0.17.2",
|
||||||
"tower",
|
"tower",
|
||||||
"tower-http",
|
"tower-http",
|
||||||
"tower-layer",
|
"tower-layer",
|
||||||
|
@ -286,6 +322,18 @@ version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chrono"
|
||||||
|
version = "0.4.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f"
|
||||||
|
dependencies = [
|
||||||
|
"iana-time-zone",
|
||||||
|
"num-integer",
|
||||||
|
"num-traits",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "codegen"
|
name = "codegen"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -300,6 +348,16 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "codespan-reporting"
|
||||||
|
version = "0.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
|
||||||
|
dependencies = [
|
||||||
|
"termcolor",
|
||||||
|
"unicode-width",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "combine"
|
name = "combine"
|
||||||
version = "4.6.6"
|
version = "4.6.6"
|
||||||
|
@ -339,6 +397,31 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crc"
|
||||||
|
version = "3.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "53757d12b596c16c78b83458d732a5d1a17ab3f53f2f7412f6fb57cc8a140ab3"
|
||||||
|
dependencies = [
|
||||||
|
"crc-catalog",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crc-catalog"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2d0165d2900ae6778e36e80bbc4da3b5eefccee9ba939761f9c2882a5d9af3ff"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-queue"
|
||||||
|
version = "0.3.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-utils"
|
name = "crossbeam-utils"
|
||||||
version = "0.8.14"
|
version = "0.8.14"
|
||||||
|
@ -358,6 +441,50 @@ dependencies = [
|
||||||
"typenum",
|
"typenum",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cxx"
|
||||||
|
version = "1.0.83"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bdf07d07d6531bfcdbe9b8b739b104610c6508dcc4d63b410585faf338241daf"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"cxxbridge-flags",
|
||||||
|
"cxxbridge-macro",
|
||||||
|
"link-cplusplus",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cxx-build"
|
||||||
|
version = "1.0.83"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d2eb5b96ecdc99f72657332953d4d9c50135af1bac34277801cc3937906ebd39"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"codespan-reporting",
|
||||||
|
"once_cell",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"scratch",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cxxbridge-flags"
|
||||||
|
version = "1.0.83"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac040a39517fd1674e0f32177648334b0f4074625b5588a64519804ba0553b12"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cxxbridge-macro"
|
||||||
|
version = "1.0.83"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1362b0ddcfc4eb0a1f57b68bd77dd99f0e826958a96abd0ae9bd092e114ffed6"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "darling"
|
name = "darling"
|
||||||
version = "0.14.2"
|
version = "0.14.2"
|
||||||
|
@ -401,8 +528,41 @@ checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"block-buffer",
|
"block-buffer",
|
||||||
"crypto-common",
|
"crypto-common",
|
||||||
|
"subtle",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dirs"
|
||||||
|
version = "4.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
|
||||||
|
dependencies = [
|
||||||
|
"dirs-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dirs-sys"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"redox_users",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dotenvy"
|
||||||
|
version = "0.15.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "03d8c417d7a8cb362e0c37e5d815f5eb7c37f79ff93707329d5a194e42e54ca0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "encoding_rs"
|
name = "encoding_rs"
|
||||||
version = "0.8.31"
|
version = "0.8.31"
|
||||||
|
@ -412,6 +572,12 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "event-listener"
|
||||||
|
version = "2.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fast_chemail"
|
name = "fast_chemail"
|
||||||
version = "0.9.6"
|
version = "0.9.6"
|
||||||
|
@ -502,6 +668,17 @@ dependencies = [
|
||||||
"futures-util",
|
"futures-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-intrusive"
|
||||||
|
version = "0.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"lock_api",
|
||||||
|
"parking_lot 0.11.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-io"
|
name = "futures-io"
|
||||||
version = "0.3.25"
|
version = "0.3.25"
|
||||||
|
@ -618,6 +795,18 @@ name = "hashbrown"
|
||||||
version = "0.12.3"
|
version = "0.12.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||||
|
dependencies = [
|
||||||
|
"ahash",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashlink"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "69fe1fcf8b4278d860ad0548329f892a3631fb63f82574df68275f34cdbe0ffa"
|
||||||
|
dependencies = [
|
||||||
|
"hashbrown",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "headers"
|
name = "headers"
|
||||||
|
@ -644,6 +833,15 @@ dependencies = [
|
||||||
"http",
|
"http",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-segmentation",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.1.19"
|
version = "0.1.19"
|
||||||
|
@ -653,6 +851,30 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hex"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hkdf"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437"
|
||||||
|
dependencies = [
|
||||||
|
"hmac",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hmac"
|
||||||
|
version = "0.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
|
||||||
|
dependencies = [
|
||||||
|
"digest",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http"
|
name = "http"
|
||||||
version = "0.2.8"
|
version = "0.2.8"
|
||||||
|
@ -730,6 +952,30 @@ dependencies = [
|
||||||
"tokio-native-tls",
|
"tokio-native-tls",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iana-time-zone"
|
||||||
|
version = "0.1.53"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765"
|
||||||
|
dependencies = [
|
||||||
|
"android_system_properties",
|
||||||
|
"core-foundation-sys",
|
||||||
|
"iana-time-zone-haiku",
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iana-time-zone-haiku"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca"
|
||||||
|
dependencies = [
|
||||||
|
"cxx",
|
||||||
|
"cxx-build",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ident_case"
|
name = "ident_case"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
@ -790,6 +1036,15 @@ version = "2.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f88c5561171189e69df9d98bcf18fd5f9558300f7ea7b801eb8a0fd748bd8745"
|
checksum = "f88c5561171189e69df9d98bcf18fd5f9558300f7ea7b801eb8a0fd748bd8745"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.10.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
|
@ -817,6 +1072,15 @@ version = "0.2.137"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
|
checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "link-cplusplus"
|
||||||
|
version = "1.0.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.9"
|
version = "0.4.9"
|
||||||
|
@ -838,9 +1102,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "matchit"
|
name = "matchit"
|
||||||
version = "0.6.0"
|
version = "0.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3dfc802da7b1cf80aefffa0c7b2f77247c8b32206cc83c270b61264f5b360a80"
|
checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "md-5"
|
||||||
|
version = "0.10.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca"
|
||||||
|
dependencies = [
|
||||||
|
"digest",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
|
@ -854,6 +1127,12 @@ version = "0.3.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
|
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "minimal-lexical"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
version = "0.8.5"
|
version = "0.8.5"
|
||||||
|
@ -902,6 +1181,26 @@ dependencies = [
|
||||||
"tempfile",
|
"tempfile",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "7.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"minimal-lexical",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-integer"
|
||||||
|
version = "0.1.45"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.15"
|
version = "0.2.15"
|
||||||
|
@ -972,6 +1271,17 @@ dependencies = [
|
||||||
"vcpkg",
|
"vcpkg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot"
|
||||||
|
version = "0.11.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
|
||||||
|
dependencies = [
|
||||||
|
"instant",
|
||||||
|
"lock_api",
|
||||||
|
"parking_lot_core 0.8.5",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
version = "0.12.1"
|
version = "0.12.1"
|
||||||
|
@ -979,7 +1289,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
|
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lock_api",
|
"lock_api",
|
||||||
"parking_lot_core",
|
"parking_lot_core 0.9.4",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot_core"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"instant",
|
||||||
|
"libc",
|
||||||
|
"redox_syscall",
|
||||||
|
"smallvec",
|
||||||
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -995,6 +1319,12 @@ dependencies = [
|
||||||
"windows-sys 0.42.0",
|
"windows-sys 0.42.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "paste"
|
||||||
|
version = "1.0.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
version = "2.2.0"
|
version = "2.2.0"
|
||||||
|
@ -1125,7 +1455,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93"
|
checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"parking_lot",
|
"parking_lot 0.12.1",
|
||||||
"scheduled-thread-pool",
|
"scheduled-thread-pool",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1189,6 +1519,17 @@ dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_users"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
"redox_syscall",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.7.0"
|
version = "1.7.0"
|
||||||
|
@ -1289,7 +1630,7 @@ version = "0.2.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "977a7519bff143a44f842fd07e80ad1329295bd71686457f18e496736f4bf9bf"
|
checksum = "977a7519bff143a44f842fd07e80ad1329295bd71686457f18e496736f4bf9bf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"parking_lot",
|
"parking_lot 0.12.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1298,6 +1639,12 @@ 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 = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scratch"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "security-framework"
|
name = "security-framework"
|
||||||
version = "2.7.0"
|
version = "2.7.0"
|
||||||
|
@ -1323,18 +1670,29 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.148"
|
version = "1.0.149"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e53f64bb4ba0191d6d0676e1b141ca55047d83b74f5607e6d8eb88126c52c2dc"
|
checksum = "256b9932320c590e707b94576e3cc1f7c9024d0ee6612dfbcf1cb106cbe8e055"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde-aux"
|
||||||
version = "1.0.148"
|
version = "4.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a55492425aa53521babf6137309e7d34c20bbfbbfcfe2c7f3a047fd1f6b92c0c"
|
checksum = "c599b3fd89a75e0c18d6d2be693ddb12cccaf771db4ff9e39097104808a014c0"
|
||||||
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.149"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b4eae9b04cbffdfd550eb462ed33bc6a1b68c935127d008b27444d08380f94e4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -1401,6 +1759,17 @@ version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012"
|
checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sha2"
|
||||||
|
version = "0.10.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cpufeatures",
|
||||||
|
"digest",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "signal-hook-registry"
|
name = "signal-hook-registry"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
|
@ -1441,18 +1810,136 @@ 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 = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09"
|
checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sqlformat"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f87e292b4291f154971a43c3774364e2cbcaec599d3f5bf6fa9d122885dbc38a"
|
||||||
|
dependencies = [
|
||||||
|
"itertools",
|
||||||
|
"nom",
|
||||||
|
"unicode_categories",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sqlx"
|
||||||
|
version = "0.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9249290c05928352f71c077cc44a464d880c63f26f7534728cca008e135c0428"
|
||||||
|
dependencies = [
|
||||||
|
"sqlx-core",
|
||||||
|
"sqlx-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sqlx-core"
|
||||||
|
version = "0.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dcbc16ddba161afc99e14d1713a453747a2b07fc097d2009f4c300ec99286105"
|
||||||
|
dependencies = [
|
||||||
|
"ahash",
|
||||||
|
"atoi",
|
||||||
|
"base64",
|
||||||
|
"bitflags",
|
||||||
|
"byteorder",
|
||||||
|
"bytes",
|
||||||
|
"crc",
|
||||||
|
"crossbeam-queue",
|
||||||
|
"dirs",
|
||||||
|
"dotenvy",
|
||||||
|
"either",
|
||||||
|
"event-listener",
|
||||||
|
"futures-channel",
|
||||||
|
"futures-core",
|
||||||
|
"futures-intrusive",
|
||||||
|
"futures-util",
|
||||||
|
"hashlink",
|
||||||
|
"hex",
|
||||||
|
"hkdf",
|
||||||
|
"hmac",
|
||||||
|
"indexmap",
|
||||||
|
"itoa",
|
||||||
|
"libc",
|
||||||
|
"log",
|
||||||
|
"md-5",
|
||||||
|
"memchr",
|
||||||
|
"once_cell",
|
||||||
|
"paste",
|
||||||
|
"percent-encoding",
|
||||||
|
"rand",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"sha1",
|
||||||
|
"sha2",
|
||||||
|
"smallvec",
|
||||||
|
"sqlformat",
|
||||||
|
"sqlx-rt",
|
||||||
|
"stringprep",
|
||||||
|
"thiserror",
|
||||||
|
"tokio-stream",
|
||||||
|
"url",
|
||||||
|
"whoami",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sqlx-macros"
|
||||||
|
version = "0.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b850fa514dc11f2ee85be9d055c512aa866746adfacd1cb42d867d68e6a5b0d9"
|
||||||
|
dependencies = [
|
||||||
|
"dotenvy",
|
||||||
|
"either",
|
||||||
|
"heck",
|
||||||
|
"once_cell",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"sha2",
|
||||||
|
"sqlx-core",
|
||||||
|
"sqlx-rt",
|
||||||
|
"syn",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sqlx-rt"
|
||||||
|
version = "0.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "24c5b2d25fa654cc5f841750b8e1cdedbe21189bf9a9382ee90bfa9dd3562396"
|
||||||
|
dependencies = [
|
||||||
|
"native-tls",
|
||||||
|
"once_cell",
|
||||||
|
"tokio",
|
||||||
|
"tokio-native-tls",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "static_assertions"
|
name = "static_assertions"
|
||||||
version = "1.1.0"
|
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 = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stringprep"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-bidi",
|
||||||
|
"unicode-normalization",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "subtle"
|
||||||
|
version = "2.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.104"
|
version = "1.0.104"
|
||||||
|
@ -1474,8 +1961,13 @@ checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8"
|
||||||
name = "tasks"
|
name = "tasks"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"async_once",
|
||||||
|
"dotenvy",
|
||||||
|
"lazy_static",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"redis",
|
"redis",
|
||||||
|
"sqlx",
|
||||||
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1508,6 +2000,15 @@ dependencies = [
|
||||||
"unic-segment",
|
"unic-segment",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "termcolor"
|
||||||
|
version = "1.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.37"
|
version = "1.0.37"
|
||||||
|
@ -1554,9 +2055,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.22.0"
|
version = "1.23.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d76ce4a75fb488c605c54bf610f221cea8b0dafb53333c1a67e8ee199dcd2ae3"
|
checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
@ -1564,12 +2065,12 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
"mio",
|
"mio",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
"parking_lot",
|
"parking_lot 0.12.1",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"signal-hook-registry",
|
"signal-hook-registry",
|
||||||
"socket2",
|
"socket2",
|
||||||
"tokio-macros",
|
"tokio-macros",
|
||||||
"winapi",
|
"windows-sys 0.42.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1593,18 +2094,41 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-stream"
|
||||||
|
version = "0.1.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-tungstenite"
|
name = "tokio-tungstenite"
|
||||||
version = "0.17.2"
|
version = "0.17.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181"
|
checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181"
|
||||||
|
dependencies = [
|
||||||
|
"futures-util",
|
||||||
|
"log",
|
||||||
|
"tokio",
|
||||||
|
"tungstenite 0.17.3",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-tungstenite"
|
||||||
|
version = "0.18.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "54319c93411147bced34cb5609a80e0a8e44c5999c93903a81cd866630ec0bfd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"log",
|
"log",
|
||||||
"native-tls",
|
"native-tls",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-native-tls",
|
"tokio-native-tls",
|
||||||
"tungstenite",
|
"tungstenite 0.18.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1649,9 +2173,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower-http"
|
name = "tower-http"
|
||||||
version = "0.3.4"
|
version = "0.3.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3c530c8675c1dbf98facee631536fa116b5fb6382d7dd6dc1b118d970eafe3ba"
|
checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
@ -1717,7 +2241,6 @@ dependencies = [
|
||||||
"http",
|
"http",
|
||||||
"httparse",
|
"httparse",
|
||||||
"log",
|
"log",
|
||||||
"native-tls",
|
|
||||||
"rand",
|
"rand",
|
||||||
"sha-1",
|
"sha-1",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
@ -1725,6 +2248,26 @@ dependencies = [
|
||||||
"utf-8",
|
"utf-8",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tungstenite"
|
||||||
|
version = "0.18.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "30ee6ab729cd4cf0fd55218530c4522ed30b7b6081752839b68fcec8d0960788"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
"byteorder",
|
||||||
|
"bytes",
|
||||||
|
"http",
|
||||||
|
"httparse",
|
||||||
|
"log",
|
||||||
|
"native-tls",
|
||||||
|
"rand",
|
||||||
|
"sha1",
|
||||||
|
"thiserror",
|
||||||
|
"url",
|
||||||
|
"utf-8",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.15.0"
|
version = "1.15.0"
|
||||||
|
@ -1808,6 +2351,24 @@ dependencies = [
|
||||||
"tinyvec",
|
"tinyvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-segmentation"
|
||||||
|
version = "1.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-width"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode_categories"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "url"
|
name = "url"
|
||||||
version = "2.3.1"
|
version = "2.3.1"
|
||||||
|
@ -1944,17 +2505,32 @@ dependencies = [
|
||||||
name = "websocket"
|
name = "websocket"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"async_once",
|
||||||
|
"axum",
|
||||||
"futures",
|
"futures",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"redis",
|
"redis",
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde-aux",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"sqlx",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-tungstenite",
|
"tokio-tungstenite 0.18.0",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "whoami"
|
||||||
|
version = "1.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d6631b6a2fd59b1841b622e8f1a7ad241ef0a46f2d580464ce8140ac94cbd571"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# Temporary deployment stuff
|
# Temporary deployment stuff.
|
||||||
|
# Passwords in this file SHOULD BE CHANGED.
|
||||||
version: '3.7'
|
version: '3.7'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
@ -10,103 +11,33 @@ services:
|
||||||
ports:
|
ports:
|
||||||
- 6379:6379
|
- 6379:6379
|
||||||
|
|
||||||
|
tsdb:
|
||||||
|
image: timescale/timescaledb:latest-pg14
|
||||||
|
environment:
|
||||||
|
POSTGRES_PASSWORD: saerro321
|
||||||
|
POSTGRES_USER: saerrouser
|
||||||
|
POSTGRES_DB: data
|
||||||
|
ports:
|
||||||
|
- 5432
|
||||||
|
|
||||||
api:
|
api:
|
||||||
image: ghcr.io/genudine/saerro/api:latest
|
image: ghcr.io/genudine/saerro/api:latest
|
||||||
pull_policy: always
|
pull_policy: always
|
||||||
ports:
|
ports:
|
||||||
- 8000:80
|
- 8000:80
|
||||||
links:
|
links:
|
||||||
- redis
|
- tsdb
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
- REDIS_HOST=redis
|
DATABASE_ADDR: postgres://saerrouser:saerro321@tsdb:$TSDB_PORT/data
|
||||||
- ROCKET_ADDRESS=0.0.0.0
|
|
||||||
|
|
||||||
ws_pc:
|
ws:
|
||||||
image: ghcr.io/genudine/saerro/websocket:latest
|
image: ghcr.io/genudine/saerro/websocket:latest
|
||||||
pull_policy: always
|
pull_policy: always
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
REDIS_ADDR: redis://redis:6379
|
DATABASE_ADDR: postgres://saerrouser:saerro321@tsdb:$TSDB_PORT/data
|
||||||
WS_ADDR: wss://push.nanite-systems.net/streaming?environment=ps2&service-id=s:saegd
|
WS_ADDR: wss://push.nanite-systems.net/streaming?environment=ps2&service-id=s:saegd
|
||||||
WORLDS: 1,10,13,17,19,40
|
WORLDS: all
|
||||||
PAIR: pc
|
|
||||||
ROLE: primary
|
|
||||||
links:
|
links:
|
||||||
- redis
|
- tsdb
|
||||||
|
|
||||||
ws_pc_backup:
|
|
||||||
image: ghcr.io/genudine/saerro/websocket:latest
|
|
||||||
pull_policy: always
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
REDIS_ADDR: redis://redis:6379
|
|
||||||
WS_ADDR: wss://push.planetside2.com/streaming?environment=ps2&service-id=s:saegd
|
|
||||||
WORLDS: 1,10,13,17,19,40
|
|
||||||
PAIR: pc
|
|
||||||
ROLE: backup
|
|
||||||
links:
|
|
||||||
- redis
|
|
||||||
|
|
||||||
ws_ps4us:
|
|
||||||
image: ghcr.io/genudine/saerro/websocket:latest
|
|
||||||
pull_policy: always
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
REDIS_ADDR: redis://redis:6379
|
|
||||||
WS_ADDR: wss://push.nanite-systems.net/streaming?environment=ps2ps4us&service-id=s:saegd
|
|
||||||
WORLDS: 1000
|
|
||||||
PAIR: ps4us
|
|
||||||
ROLE: primary
|
|
||||||
links:
|
|
||||||
- redis
|
|
||||||
|
|
||||||
ws_ps4us_backup:
|
|
||||||
image: ghcr.io/genudine/saerro/websocket:latest
|
|
||||||
pull_policy: always
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
REDIS_ADDR: redis://redis:6379
|
|
||||||
WS_ADDR: wss://push.planetside2.com/streaming?environment=ps2ps4us&service-id=s:saegd
|
|
||||||
WORLDS: 1000
|
|
||||||
PAIR: ps4us
|
|
||||||
ROLE: backup
|
|
||||||
links:
|
|
||||||
- redis
|
|
||||||
|
|
||||||
|
|
||||||
ws_ps4eu:
|
|
||||||
image: ghcr.io/genudine/saerro/websocket:latest
|
|
||||||
pull_policy: always
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
REDIS_ADDR: redis://redis:6379
|
|
||||||
WS_ADDR: wss://push.nanite-systems.net/streaming?environment=ps2ps4eu&service-id=s:saegd
|
|
||||||
WORLDS: 2000
|
|
||||||
PAIR: ps4eu
|
|
||||||
ROLE: primary
|
|
||||||
links:
|
|
||||||
- redis
|
|
||||||
|
|
||||||
ws_ps4eu_backup:
|
|
||||||
image: ghcr.io/genudine/saerro/websocket:latest
|
|
||||||
pull_policy: always
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
REDIS_ADDR: redis://redis:6379
|
|
||||||
WS_ADDR: wss://push.planetside2.com/streaming?environment=ps2ps4eu&service-id=s:saegd
|
|
||||||
WORLDS: 2000
|
|
||||||
PAIR: ps4eu
|
|
||||||
ROLE: backup
|
|
||||||
links:
|
|
||||||
- redis
|
|
||||||
|
|
||||||
task_prune:
|
|
||||||
image: ghcr.io/genudine/saerro/tasks:latest
|
|
||||||
command: /app prune
|
|
||||||
pull_policy: always
|
|
||||||
restart: "no"
|
|
||||||
environment:
|
|
||||||
REDIS_ADDR: redis://redis:6379
|
|
||||||
links:
|
|
||||||
- redis
|
|
||||||
|
|
|
@ -5,6 +5,14 @@ services:
|
||||||
image: redis
|
image: redis
|
||||||
command: redis-server --save "" --appendonly no
|
command: redis-server --save "" --appendonly no
|
||||||
container_name: redis
|
container_name: redis
|
||||||
restart: always
|
|
||||||
ports:
|
ports:
|
||||||
- "6379:6379"
|
- "6379:6379"
|
||||||
|
|
||||||
|
tsdb:
|
||||||
|
image: timescale/timescaledb:latest-pg14
|
||||||
|
environment:
|
||||||
|
POSTGRES_PASSWORD: saerro321
|
||||||
|
POSTGRES_USER: saerrouser
|
||||||
|
POSTGRES_DB: data
|
||||||
|
ports:
|
||||||
|
- 5432:5432
|
||||||
|
|
|
@ -8,10 +8,11 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
redis = { version = "0.22.1", features = ["aio", "r2d2", "tokio-comp"] }
|
redis = { version = "0.22.1", features = ["aio", "r2d2", "tokio-comp"] }
|
||||||
serde_json = "1.0.89"
|
serde_json = "1.0.89"
|
||||||
serde = "1.0.148"
|
serde = "1.0.149"
|
||||||
async-graphql = { version = "5.0.2" }
|
async-graphql = { version = "5.0.2" }
|
||||||
async-graphql-axum = "5.0.2"
|
async-graphql-axum = "5.0.2"
|
||||||
axum = "0.6.0"
|
axum = "0.6.1"
|
||||||
tokio = { version = "1.22.0" }
|
sqlx = { version = "0.6.2", features = [ "runtime-tokio-native-tls" , "postgres" ] }
|
||||||
tower-http = { version = "0.3.4", features = ["cors"] }
|
tokio = { version = "1.23.0", features = [ "full" ] }
|
||||||
|
tower-http = { version = "0.3.5", features = ["cors"] }
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
|
@ -6,8 +6,7 @@ mod vehicles;
|
||||||
mod world;
|
mod world;
|
||||||
|
|
||||||
use async_graphql::{
|
use async_graphql::{
|
||||||
http::{playground_source, GraphQLPlaygroundConfig},
|
http::GraphiQLSource, EmptyMutation, EmptySubscription, Request, Response, Schema,
|
||||||
EmptyMutation, EmptySubscription, Request, Response, Schema,
|
|
||||||
};
|
};
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::Query,
|
extract::Query,
|
||||||
|
@ -42,13 +41,19 @@ async fn graphql_handler_get(
|
||||||
query: Query<Request>,
|
query: Query<Request>,
|
||||||
) -> axum::response::Response {
|
) -> axum::response::Response {
|
||||||
if query.query == "" {
|
if query.query == "" {
|
||||||
return Redirect::to("/graphql/playground").into_response();
|
return Redirect::to("/graphiql").into_response();
|
||||||
}
|
}
|
||||||
|
|
||||||
Json(schema.execute(query.0).await).into_response()
|
Json(schema.execute(query.0).await).into_response()
|
||||||
}
|
}
|
||||||
async fn graphql_playground() -> impl IntoResponse {
|
|
||||||
Html(playground_source(GraphQLPlaygroundConfig::new("/graphql")))
|
async fn graphiql() -> impl IntoResponse {
|
||||||
|
Html(
|
||||||
|
GraphiQLSource::build()
|
||||||
|
.endpoint("/graphql")
|
||||||
|
.title("Saerro Listening Post")
|
||||||
|
.finish(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
|
@ -76,7 +81,7 @@ async fn main() {
|
||||||
"/graphql",
|
"/graphql",
|
||||||
post(graphql_handler_post).get(graphql_handler_get),
|
post(graphql_handler_post).get(graphql_handler_get),
|
||||||
)
|
)
|
||||||
.route("/graphql/playground", get(graphql_playground))
|
.route("/graphql/playground", get(graphiql))
|
||||||
.fallback(handle_404)
|
.fallback(handle_404)
|
||||||
.layer(Extension(redis))
|
.layer(Extension(redis))
|
||||||
.layer(Extension(schema))
|
.layer(Extension(schema))
|
||||||
|
|
|
@ -6,5 +6,10 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
redis = { version = "0.22.1", default_features = false, features = [] }
|
redis = { version = "0.22.1", features = ["aio", "r2d2", "tokio-comp"] }
|
||||||
once_cell = "1.16.0"
|
once_cell = "1.16.0"
|
||||||
|
tokio = { version = "1.23.0", features = ["full"] }
|
||||||
|
sqlx = { version = "0.6.2", features = [ "runtime-tokio-native-tls" , "postgres" ] }
|
||||||
|
lazy_static = "1.4.0"
|
||||||
|
async_once = "0.2.6"
|
||||||
|
dotenvy = "0.15.6"
|
|
@ -1,14 +1,29 @@
|
||||||
|
use async_once::AsyncOnce;
|
||||||
|
use dotenvy::dotenv;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use migrations::cmd_migrate;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use redis::Commands;
|
use redis::Commands;
|
||||||
|
use sqlx::query;
|
||||||
use std::env::args;
|
use std::env::args;
|
||||||
use std::ops::Sub;
|
use std::ops::Sub;
|
||||||
use std::time::{Duration, SystemTime};
|
use std::time::{Duration, SystemTime};
|
||||||
|
|
||||||
|
mod migrations;
|
||||||
|
|
||||||
pub static REDIS_CLIENT: Lazy<redis::Client> = Lazy::new(|| {
|
pub static REDIS_CLIENT: Lazy<redis::Client> = Lazy::new(|| {
|
||||||
redis::Client::open(std::env::var("REDIS_ADDR").unwrap_or("redis://localhost:6379".to_string()))
|
redis::Client::open(std::env::var("REDIS_ADDR").unwrap_or("redis://localhost:6379".to_string()))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref PG: AsyncOnce<sqlx::PgPool> = AsyncOnce::new(async {
|
||||||
|
let db_url = std::env::var("DATABASE_URL")
|
||||||
|
.unwrap_or("postgres://saerrouser:saerro321@localhost:5432/data".to_string());
|
||||||
|
sqlx::PgPool::connect(&db_url).await.unwrap()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
fn cmd_prune() {
|
fn cmd_prune() {
|
||||||
println!("Pruning old data...");
|
println!("Pruning old data...");
|
||||||
let mut con = REDIS_CLIENT.get_connection().unwrap();
|
let mut con = REDIS_CLIENT.get_connection().unwrap();
|
||||||
|
@ -46,14 +61,19 @@ fn cmd_help() {
|
||||||
println!("Commands:");
|
println!("Commands:");
|
||||||
println!(" help - Show this help message");
|
println!(" help - Show this help message");
|
||||||
println!(" prune - Remove stale data from Redis");
|
println!(" prune - Remove stale data from Redis");
|
||||||
|
println!(" migrate - Reset and create database tables");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
dotenv().ok();
|
||||||
|
|
||||||
let command = args().nth(1).unwrap_or("help".to_string());
|
let command = args().nth(1).unwrap_or("help".to_string());
|
||||||
|
|
||||||
match command.as_str() {
|
match command.as_str() {
|
||||||
"help" => cmd_help(),
|
"help" => cmd_help(),
|
||||||
"prune" => cmd_prune(),
|
"prune" => cmd_prune(),
|
||||||
|
"migrate" => cmd_migrate().await,
|
||||||
_ => {
|
_ => {
|
||||||
println!("Unknown command: {}", command);
|
println!("Unknown command: {}", command);
|
||||||
cmd_help();
|
cmd_help();
|
||||||
|
|
137
services/tasks/src/migrations.rs
Normal file
137
services/tasks/src/migrations.rs
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
use crate::PG;
|
||||||
|
use sqlx::query;
|
||||||
|
|
||||||
|
pub async fn cmd_migrate() {
|
||||||
|
println!("Migrating database...");
|
||||||
|
|
||||||
|
tokio::join!(migrate_players(), migrate_classes(), migrate_vehicles(),);
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn migrate_players() {
|
||||||
|
let pool = PG.get().await;
|
||||||
|
|
||||||
|
println!("-> Migrating players");
|
||||||
|
|
||||||
|
println!("PLAYERS => DROP TABLE IF EXISTS players");
|
||||||
|
query("DROP TABLE IF EXISTS players")
|
||||||
|
.execute(pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!("PLAYERS => CREATE TABLE players");
|
||||||
|
query(
|
||||||
|
"CREATE TABLE players (
|
||||||
|
time TIMESTAMPTZ NOT NULL,
|
||||||
|
character_id TEXT NOT NULL,
|
||||||
|
world_id INT NOT NULL,
|
||||||
|
faction_id INT NOT NULL,
|
||||||
|
zone_id INT NOT NULL);",
|
||||||
|
)
|
||||||
|
.execute(pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!("PLAYERS => create_hypertable");
|
||||||
|
query(
|
||||||
|
"SELECT create_hypertable('players', 'time',
|
||||||
|
chunk_time_interval => INTERVAL '1 minute', if_not_exists => TRUE);",
|
||||||
|
)
|
||||||
|
.execute(pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!("PLAYERS => add_retention_policy");
|
||||||
|
query("SELECT add_retention_policy('players', INTERVAL '15 minutes');")
|
||||||
|
.execute(pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!("PLAYERS => done!");
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn migrate_classes() {
|
||||||
|
let pool = PG.get().await;
|
||||||
|
|
||||||
|
println!("-> Migrating classes");
|
||||||
|
|
||||||
|
println!("CLASSES => DROP TABLE IF EXISTS classes");
|
||||||
|
query("DROP TABLE IF EXISTS classes")
|
||||||
|
.execute(pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!("CLASSES => CREATE TABLE classes");
|
||||||
|
query(
|
||||||
|
"CREATE TABLE classes (
|
||||||
|
time TIMESTAMPTZ NOT NULL,
|
||||||
|
character_id TEXT NOT NULL,
|
||||||
|
world_id INT NOT NULL,
|
||||||
|
faction_id INT NOT NULL,
|
||||||
|
zone_id INT NOT NULL,
|
||||||
|
class_id TEXT NOT NULL);",
|
||||||
|
)
|
||||||
|
.execute(pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!("CLASSES => create_hypertable");
|
||||||
|
query(
|
||||||
|
"SELECT create_hypertable('classes', 'time',
|
||||||
|
chunk_time_interval => INTERVAL '1 minute', if_not_exists => TRUE);",
|
||||||
|
)
|
||||||
|
.execute(pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!("CLASSES => add_retention_policy");
|
||||||
|
query("SELECT add_retention_policy('classes', INTERVAL '15 minutes');")
|
||||||
|
.execute(pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!("CLASSES => done!");
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn migrate_vehicles() {
|
||||||
|
let pool = PG.get().await;
|
||||||
|
|
||||||
|
println!("-> Migrating vehicles");
|
||||||
|
|
||||||
|
println!("VEHICLES => DROP TABLE IF EXISTS vehicles");
|
||||||
|
query("DROP TABLE IF EXISTS vehicles")
|
||||||
|
.execute(pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!("VEHICLES => CREATE TABLE vehicles");
|
||||||
|
query(
|
||||||
|
"CREATE TABLE vehicles (
|
||||||
|
time TIMESTAMPTZ NOT NULL,
|
||||||
|
character_id TEXT NOT NULL,
|
||||||
|
world_id INT NOT NULL,
|
||||||
|
faction_id INT NOT NULL,
|
||||||
|
zone_id INT NOT NULL,
|
||||||
|
vehicle_id TEXT NOT NULL);",
|
||||||
|
)
|
||||||
|
.execute(pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!("VEHICLES => create_hypertable");
|
||||||
|
query(
|
||||||
|
"SELECT create_hypertable('vehicles', 'time',
|
||||||
|
chunk_time_interval => INTERVAL '1 minute', if_not_exists => TRUE);",
|
||||||
|
)
|
||||||
|
.execute(pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!("VEHICLES => add_retention_policy");
|
||||||
|
|
||||||
|
query("SELECT add_retention_policy('vehicles', INTERVAL '15 minutes');")
|
||||||
|
.execute(pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!("VEHICLES => done!");
|
||||||
|
}
|
|
@ -8,10 +8,14 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
redis = { version = "0.22.1", default_features = false, features = ["r2d2"] }
|
redis = { version = "0.22.1", default_features = false, features = ["r2d2"] }
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
tokio-tungstenite = { version = "0.17.2", features=["native-tls"] }
|
tokio-tungstenite = { version = "0.18.0", features=["native-tls"] }
|
||||||
|
serde = { version = "1.0.149", features = ["derive"] }
|
||||||
serde_json = "1.0.89"
|
serde_json = "1.0.89"
|
||||||
serde = { version = "1.0.148", features = ["derive"] }
|
tokio = { version = "1.23.0", features = ["full"] }
|
||||||
tokio = { version = "1.22.0" }
|
sqlx = { version = "0.6.2", features = [ "runtime-tokio-native-tls" , "postgres" ] }
|
||||||
url = "2.3.1"
|
url = "2.3.1"
|
||||||
futures-util = "0.3.25"
|
futures-util = "0.3.25"
|
||||||
futures = "0.3.25"
|
futures = "0.3.25"
|
||||||
|
async_once = "0.2.6"
|
||||||
|
serde-aux = "4.1.2"
|
||||||
|
axum = "0.6.1"
|
|
@ -1,24 +1,27 @@
|
||||||
|
use async_once::AsyncOnce;
|
||||||
|
use axum::{routing::get, Router};
|
||||||
use futures::{pin_mut, FutureExt};
|
use futures::{pin_mut, FutureExt};
|
||||||
use futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use redis::Commands;
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
use serde_aux::prelude::*;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use std::{env, time::SystemTime};
|
use sqlx::{postgres::PgPoolOptions, query};
|
||||||
|
use std::{env, net::SocketAddr, time::Duration};
|
||||||
|
use tokio::task::JoinSet;
|
||||||
use tokio_tungstenite::{connect_async, tungstenite::Message};
|
use tokio_tungstenite::{connect_async, tungstenite::Message};
|
||||||
|
|
||||||
mod translators;
|
mod translators;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref REDIS_CLIENT: redis::Client = redis::Client::open(format!(
|
|
||||||
"redis://{}:{}",
|
|
||||||
std::env::var("REDIS_HOST").unwrap_or("localhost".to_string()),
|
|
||||||
std::env::var("REDIS_PORT").unwrap_or("6379".to_string()),
|
|
||||||
))
|
|
||||||
.unwrap();
|
|
||||||
static ref PAIR: String = env::var("PAIR").unwrap_or_default();
|
static ref PAIR: String = env::var("PAIR").unwrap_or_default();
|
||||||
static ref ROLE: String = env::var("ROLE").unwrap_or("primary".to_string());
|
static ref ROLE: String = env::var("ROLE").unwrap_or("primary".to_string());
|
||||||
static ref WS_ADDR: String = env::var("WS_ADDR").unwrap_or_default();
|
static ref WS_ADDR: String = env::var("WS_ADDR").unwrap_or_default();
|
||||||
|
static ref PG: AsyncOnce<sqlx::PgPool> = AsyncOnce::new(async {
|
||||||
|
let db_url = std::env::var("DATABASE_URL")
|
||||||
|
.unwrap_or("postgres://saerrouser:saerro321@localhost:5432/data".to_string());
|
||||||
|
PgPoolOptions::new().connect(&db_url).await.unwrap()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_init(tx: futures::channel::mpsc::UnboundedSender<Message>) {
|
async fn send_init(tx: futures::channel::mpsc::UnboundedSender<Message>) {
|
||||||
|
@ -42,54 +45,69 @@ async fn send_init(tx: futures::channel::mpsc::UnboundedSender<Message>) {
|
||||||
tx.unbounded_send(Message::text(setup_msg.to_string()))
|
tx.unbounded_send(Message::text(setup_msg.to_string()))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
println!("Sent setup message");
|
println!("[ws] Sent setup message");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
struct PopEvent {
|
struct PopEvent {
|
||||||
world_id: String,
|
world_id: i32,
|
||||||
team_id: String,
|
team_id: i32,
|
||||||
character_id: String,
|
character_id: String,
|
||||||
timestamp: u64,
|
zone_id: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct VehicleEvent {
|
struct VehicleEvent {
|
||||||
world_id: String,
|
world_id: i32,
|
||||||
vehicle_id: String,
|
vehicle_id: String,
|
||||||
character_id: String,
|
character_id: String,
|
||||||
timestamp: u64,
|
zone_id: i32,
|
||||||
|
team_id: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ClassEvent {
|
struct ClassEvent {
|
||||||
world_id: String,
|
world_id: i32,
|
||||||
character_id: String,
|
character_id: String,
|
||||||
loadout_id: String,
|
loadout_id: String,
|
||||||
timestamp: u64,
|
zone_id: i32,
|
||||||
|
team_id: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// async fn track_pop(pop_event: PopEvent) {
|
||||||
|
// track_pop_db(pop_event.clone()).await;
|
||||||
|
// track_pop_redis(pop_event).await;
|
||||||
|
// }
|
||||||
|
|
||||||
async fn track_pop(pop_event: PopEvent) {
|
async fn track_pop(pop_event: PopEvent) {
|
||||||
let mut con = REDIS_CLIENT.get_connection().unwrap();
|
// println!("[ws/track_pop]");
|
||||||
|
let pool = PG.get().await;
|
||||||
|
|
||||||
let PopEvent {
|
let PopEvent {
|
||||||
world_id,
|
world_id,
|
||||||
team_id,
|
team_id,
|
||||||
character_id,
|
character_id,
|
||||||
timestamp,
|
zone_id,
|
||||||
} = pop_event;
|
} = pop_event;
|
||||||
|
|
||||||
let key = format!("wp:{}/{}", world_id, team_id);
|
query("INSERT INTO players (time, character_id, world_id, faction_id, zone_id) VALUES (now(), $1, $2, $3, $4);")
|
||||||
let _: () = con.zadd(key, character_id.clone(), timestamp).unwrap();
|
.bind(character_id)
|
||||||
let key = format!("wp:{}", world_id);
|
.bind(world_id)
|
||||||
let _: () = con.zadd(key, character_id, timestamp).unwrap();
|
.bind(team_id)
|
||||||
|
.bind(zone_id)
|
||||||
|
.execute(pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn track_vehicle(vehicle_event: VehicleEvent) {
|
async fn track_vehicle(vehicle_event: VehicleEvent) {
|
||||||
let mut con = REDIS_CLIENT.get_connection().unwrap();
|
// println!("[ws/track_vehicle]");
|
||||||
|
let pool = PG.get().await;
|
||||||
|
|
||||||
let VehicleEvent {
|
let VehicleEvent {
|
||||||
world_id,
|
world_id,
|
||||||
vehicle_id,
|
vehicle_id,
|
||||||
timestamp,
|
zone_id,
|
||||||
character_id,
|
character_id,
|
||||||
|
team_id,
|
||||||
} = vehicle_event;
|
} = vehicle_event;
|
||||||
|
|
||||||
let vehicle_name = translators::vehicle_to_name(vehicle_id.as_str());
|
let vehicle_name = translators::vehicle_to_name(vehicle_id.as_str());
|
||||||
|
@ -98,18 +116,27 @@ async fn track_vehicle(vehicle_event: VehicleEvent) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let key = format!("v:{}/{}", world_id, vehicle_name);
|
query("INSERT INTO vehicles (time, character_id, world_id, faction_id, zone_id, vehicle_id) VALUES (now(), $1, $2, $3, $4, $5);")
|
||||||
let _: () = con.zadd(key, character_id, timestamp).unwrap();
|
.bind(character_id)
|
||||||
|
.bind(world_id)
|
||||||
|
.bind(team_id)
|
||||||
|
.bind(zone_id)
|
||||||
|
.bind(vehicle_name)
|
||||||
|
.execute(pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn track_class(class_event: ClassEvent) {
|
async fn track_class(class_event: ClassEvent) {
|
||||||
let mut con = REDIS_CLIENT.get_connection().unwrap();
|
// println!("[ws/track_class]");
|
||||||
|
let pool = PG.get().await;
|
||||||
|
|
||||||
let ClassEvent {
|
let ClassEvent {
|
||||||
world_id,
|
world_id,
|
||||||
character_id,
|
character_id,
|
||||||
loadout_id,
|
loadout_id,
|
||||||
timestamp,
|
zone_id,
|
||||||
|
team_id,
|
||||||
} = class_event;
|
} = class_event;
|
||||||
|
|
||||||
let class_name = translators::loadout_to_class(loadout_id.as_str());
|
let class_name = translators::loadout_to_class(loadout_id.as_str());
|
||||||
|
@ -118,108 +145,107 @@ async fn track_class(class_event: ClassEvent) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let key = format!("c:{}/{}", world_id, class_name);
|
query(
|
||||||
let _: () = con.zadd(key, character_id, timestamp).unwrap();
|
"INSERT INTO classes (
|
||||||
|
time,
|
||||||
|
character_id,
|
||||||
|
world_id,
|
||||||
|
faction_id,
|
||||||
|
zone_id,
|
||||||
|
class_id
|
||||||
|
) VALUES (now(), $1, $2, $3, $4, $5);",
|
||||||
|
)
|
||||||
|
.bind(character_id)
|
||||||
|
.bind(world_id)
|
||||||
|
.bind(team_id)
|
||||||
|
.bind(zone_id)
|
||||||
|
.bind(class_name)
|
||||||
|
.execute(pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn should_process_event() -> bool {
|
async fn process_event(event: &Event) {
|
||||||
let mut con = REDIS_CLIENT.get_connection().unwrap();
|
let mut set = JoinSet::new();
|
||||||
let role: String = ROLE.parse().unwrap();
|
// println!("[ws/process_event] EVENT: {:?}", event);
|
||||||
|
if event.character_id != "0" {
|
||||||
let heartbeat_key = format!("heartbeat:{}:{}", PAIR.to_string(), role);
|
|
||||||
let _: () = con.set_ex(heartbeat_key, "1", 60).unwrap();
|
|
||||||
|
|
||||||
if role == "primary" {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let primary_heartbeat_key = format!("heartbeat:{}:primary", PAIR.to_string());
|
|
||||||
match con.get(primary_heartbeat_key) {
|
|
||||||
Ok(1) => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn process_event(event: &Event) {
|
|
||||||
if should_process_event() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let timestamp = SystemTime::now()
|
|
||||||
.duration_since(SystemTime::UNIX_EPOCH)
|
|
||||||
.unwrap()
|
|
||||||
.as_secs();
|
|
||||||
|
|
||||||
// General population tracking
|
// General population tracking
|
||||||
track_pop(PopEvent {
|
set.spawn(track_pop(PopEvent {
|
||||||
world_id: event.world_id.clone(),
|
world_id: event.world_id.clone(),
|
||||||
team_id: event.team_id.clone(),
|
team_id: event.team_id.clone(),
|
||||||
character_id: event.character_id.clone(),
|
character_id: event.character_id.clone(),
|
||||||
timestamp,
|
zone_id: event.zone_id.clone(),
|
||||||
})
|
}));
|
||||||
.now_or_never();
|
}
|
||||||
|
|
||||||
if event.event_name == "VehicleDestroy" {
|
if event.event_name == "VehicleDestroy" {
|
||||||
track_vehicle(VehicleEvent {
|
set.spawn(track_vehicle(VehicleEvent {
|
||||||
world_id: event.world_id.clone(),
|
world_id: event.world_id.clone(),
|
||||||
vehicle_id: event.vehicle_id.clone(),
|
vehicle_id: event.vehicle_id.clone(),
|
||||||
character_id: event.character_id.clone(),
|
character_id: event.character_id.clone(),
|
||||||
timestamp,
|
zone_id: event.zone_id.clone(),
|
||||||
})
|
team_id: event.team_id.clone(),
|
||||||
.now_or_never();
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if event.event_name == "Death" {
|
if event.event_name == "Death" {
|
||||||
track_class(ClassEvent {
|
set.spawn(track_class(ClassEvent {
|
||||||
world_id: event.world_id.clone(),
|
world_id: event.world_id.clone(),
|
||||||
character_id: event.character_id.clone(),
|
character_id: event.character_id.clone(),
|
||||||
loadout_id: event.loadout_id.clone(),
|
loadout_id: event.loadout_id.clone(),
|
||||||
timestamp,
|
zone_id: event.zone_id.clone(),
|
||||||
})
|
team_id: event.team_id.clone(),
|
||||||
.now_or_never();
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if event.attacker_character_id != ""
|
if event.attacker_character_id != ""
|
||||||
&& (event.attacker_team_id != "" || event.attacker_team_id != "0")
|
&& event.attacker_character_id != "0"
|
||||||
|
&& (event.attacker_team_id != 0 || event.attacker_team_id != 0)
|
||||||
{
|
{
|
||||||
track_pop(PopEvent {
|
set.spawn(track_pop(PopEvent {
|
||||||
world_id: event.world_id.clone(),
|
world_id: event.world_id.clone(),
|
||||||
team_id: event.attacker_team_id.clone(),
|
team_id: event.attacker_team_id.clone(),
|
||||||
character_id: event.attacker_character_id.clone(),
|
character_id: event.attacker_character_id.clone(),
|
||||||
timestamp,
|
zone_id: event.zone_id.clone(),
|
||||||
})
|
}));
|
||||||
.now_or_never();
|
|
||||||
|
|
||||||
if event.event_name == "VehicleDestroy" {
|
if event.event_name == "VehicleDestroy" {
|
||||||
track_vehicle(VehicleEvent {
|
set.spawn(track_vehicle(VehicleEvent {
|
||||||
world_id: event.world_id.clone(),
|
world_id: event.world_id.clone(),
|
||||||
vehicle_id: event.attacker_vehicle_id.clone(),
|
vehicle_id: event.attacker_vehicle_id.clone(),
|
||||||
character_id: event.attacker_character_id.clone(),
|
character_id: event.attacker_character_id.clone(),
|
||||||
timestamp,
|
zone_id: event.zone_id.clone(),
|
||||||
})
|
team_id: event.attacker_team_id.clone(),
|
||||||
.now_or_never();
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if event.event_name == "Death" {
|
if event.event_name == "Death" {
|
||||||
track_class(ClassEvent {
|
set.spawn(track_class(ClassEvent {
|
||||||
world_id: event.world_id.clone(),
|
world_id: event.world_id.clone(),
|
||||||
character_id: event.attacker_character_id.clone(),
|
character_id: event.attacker_character_id.clone(),
|
||||||
loadout_id: event.attacker_loadout_id.clone(),
|
loadout_id: event.attacker_loadout_id.clone(),
|
||||||
timestamp,
|
zone_id: event.zone_id.clone(),
|
||||||
})
|
team_id: event.attacker_team_id.clone(),
|
||||||
.now_or_never();
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while let Some(_) = set.join_next().await {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
#[derive(Deserialize, Debug, Clone, Default)]
|
||||||
struct Event {
|
struct Event {
|
||||||
event_name: String,
|
event_name: String,
|
||||||
world_id: String,
|
#[serde(deserialize_with = "deserialize_number_from_string")]
|
||||||
|
world_id: i32,
|
||||||
character_id: String,
|
character_id: String,
|
||||||
attacker_character_id: String,
|
attacker_character_id: String,
|
||||||
attacker_team_id: String,
|
#[serde(deserialize_with = "deserialize_number_from_string")]
|
||||||
team_id: String,
|
attacker_team_id: i32,
|
||||||
|
#[serde(deserialize_with = "deserialize_number_from_string")]
|
||||||
|
team_id: i32,
|
||||||
|
#[serde(deserialize_with = "deserialize_number_from_string")]
|
||||||
|
zone_id: i32,
|
||||||
|
|
||||||
// Class Tracking
|
// Class Tracking
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
@ -239,23 +265,22 @@ struct Payload {
|
||||||
payload: Event,
|
payload: Event,
|
||||||
}
|
}
|
||||||
|
|
||||||
// /// Send a longer heartbeat in case this is PS4EU and gets like one event per hour
|
async fn healthz() {
|
||||||
// async fn heartbeat() {
|
let app = Router::new().route("/healthz", get(|| async { "ok" }));
|
||||||
// let mut interval = tokio::time::interval(Duration::from_secs(150));
|
|
||||||
// loop {
|
let port: u16 = std::env::var("PORT")
|
||||||
// interval.tick().await;
|
.unwrap_or("8999".to_string())
|
||||||
// let mut con = REDIS_CLIENT.get_connection().unwrap();
|
.parse()
|
||||||
// let role: String = ROLE.parse().unwrap();
|
.unwrap();
|
||||||
// let heartbeat_key = format!("heartbeat:{}:{}", PAIR.to_string(), role);
|
let addr = SocketAddr::from(([0, 0, 0, 0], port));
|
||||||
// let response: Option<String> = con.get(heartbeat_key.clone()).unwrap();
|
|
||||||
// match response {
|
println!("[healthz] Listening on http://{}", addr);
|
||||||
// None => {
|
|
||||||
// let _: () = con.set_ex(heartbeat_key, "1", 300).unwrap();
|
axum::Server::bind(&addr)
|
||||||
// }
|
.serve(app.into_make_service())
|
||||||
// _ => (),
|
.await
|
||||||
// }
|
.unwrap();
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
|
@ -273,42 +298,27 @@ async fn main() {
|
||||||
let fused_writer = rx.map(Ok).forward(write).fuse();
|
let fused_writer = rx.map(Ok).forward(write).fuse();
|
||||||
let fused_reader = read
|
let fused_reader = read
|
||||||
.for_each(|msg| async move {
|
.for_each(|msg| async move {
|
||||||
// println!("Processing event: {:?}", msg);
|
|
||||||
|
|
||||||
let body = &msg.unwrap().to_string();
|
let body = &msg.unwrap().to_string();
|
||||||
let data: Payload = serde_json::from_str(body).unwrap_or(Payload {
|
let data: Payload = serde_json::from_str(body).unwrap_or(Payload {
|
||||||
payload: Event {
|
payload: Event::default(),
|
||||||
event_name: "".to_string(),
|
|
||||||
world_id: "".to_string(),
|
|
||||||
character_id: "".to_string(),
|
|
||||||
attacker_character_id: "".to_string(),
|
|
||||||
attacker_team_id: "".to_string(),
|
|
||||||
team_id: "".to_string(),
|
|
||||||
attacker_loadout_id: "".to_string(),
|
|
||||||
loadout_id: "".to_string(),
|
|
||||||
vehicle_id: "".to_string(),
|
|
||||||
attacker_vehicle_id: "".to_string(),
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if data.payload.event_name == "" {
|
if data.payload.event_name == "" {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
process_event(&data.payload);
|
process_event(&data.payload).await;
|
||||||
})
|
})
|
||||||
.fuse();
|
.fuse();
|
||||||
|
|
||||||
pin_mut!(fused_writer, fused_reader);
|
pin_mut!(fused_writer, fused_reader);
|
||||||
|
|
||||||
let init = tokio::spawn(send_init(tx.clone()));
|
let init = tokio::spawn(send_init(tx.clone()));
|
||||||
|
let mut healthz = tokio::spawn(healthz()).fuse();
|
||||||
futures::select! {
|
futures::select! {
|
||||||
_ = fused_reader => {}
|
_ = fused_reader => {}
|
||||||
_ = fused_writer => {}
|
_ = fused_writer => {}
|
||||||
|
_ = healthz => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// tokio::spawn(heartbeat());
|
|
||||||
|
|
||||||
init.await.unwrap();
|
init.await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue