Add caching with LRU cache under mutex

Caches responses of each GET handler in a separate capacity-limited cache (as a
custom clone-able `CachedResponse` struct). Subsequent requests will build a
`Response` from the cached bytes instead of re-querying the database and
re-serializing the JSON. This greatly speeds up the list endpoints and
`get_interior_ref_list`.

Also caches the api-key-to-id mapping for `Owner`s in order to speed up frequent
authentications.

Each create handler clears the entire list response cache. Each delete handler
also clears the entire list response cache and deletes the cached response for
that key. Deleting an owner also deletes their entry in the
`owner_ids_by_api_key` cache.
This commit is contained in:
Tyler Hallada 2020-08-01 00:25:04 -04:00
parent 68b04b4f4c
commit 519fcb4c5a
14 changed files with 470 additions and 123 deletions

141
Cargo.lock generated
View File

@ -5,6 +5,14 @@ name = "adler"
version = "0.2.3" version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ahash"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"const-random 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "0.7.13" version = "0.7.13"
@ -103,7 +111,7 @@ version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"hermit-abi 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "hermit-abi 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -274,13 +282,31 @@ dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "const-random"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"const-random-macro 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro-hack 0.5.18 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "const-random-macro"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro-hack 0.5.18 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "core-foundation" name = "core-foundation"
version = "0.7.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"
dependencies = [ dependencies = [
"core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -382,7 +408,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
"miniz_oxide 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "miniz_oxide 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -532,7 +558,7 @@ version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
"wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)", "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -551,7 +577,16 @@ dependencies = [
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "tracing 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hashbrown"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ahash 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -598,7 +633,7 @@ name = "hermit-abi"
version = "0.1.15" version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -678,7 +713,7 @@ dependencies = [
"time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "tracing 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
"want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -719,7 +754,7 @@ name = "iovec"
version = "0.1.4" version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -751,7 +786,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.73" version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
@ -759,7 +794,7 @@ name = "listenfd"
version = "0.3.3" version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -788,6 +823,14 @@ dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "lru"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"hashbrown 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "maplit" name = "maplit"
version = "1.0.2" version = "1.0.2"
@ -882,7 +925,7 @@ dependencies = [
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
@ -907,7 +950,7 @@ version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -954,7 +997,7 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl 0.10.30 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.10.30 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -971,7 +1014,7 @@ version = "0.2.34"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -998,7 +1041,7 @@ version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"hermit-abi 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "hermit-abi 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -1025,7 +1068,7 @@ dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.58 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.58 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -1041,7 +1084,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
"vcpkg 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -1069,7 +1112,7 @@ dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"cloudabi 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "cloudabi 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"instant 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "instant 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1257,7 +1300,7 @@ version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1275,7 +1318,7 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1349,7 +1392,7 @@ name = "rand_jitter"
version = "0.1.4" version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -1361,7 +1404,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1516,7 +1559,7 @@ dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
"security-framework-sys 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework-sys 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -1526,7 +1569,7 @@ version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -1617,21 +1660,24 @@ dependencies = [
"anyhow 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", "anyhow 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"async-trait 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", "async-trait 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
"barrel 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "barrel 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 3.0.0-beta.1 (registry+https://github.com/rust-lang/crates.io-index)", "clap 3.0.0-beta.1 (registry+https://github.com/rust-lang/crates.io-index)",
"dotenv 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "dotenv 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"http-api-problem 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "http-api-problem 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.13.7 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.13.7 (registry+https://github.com/rust-lang/crates.io-index)",
"ipnetwork 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", "ipnetwork 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
"listenfd 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "listenfd 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"lru 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"refinery 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "refinery 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)",
"sqlx 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "sqlx 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "tracing 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing-futures 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "tracing-futures 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing-subscriber 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", "tracing-subscriber 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
"url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"warp 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "warp 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1643,7 +1689,7 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"arc-swap 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "arc-swap 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -1672,7 +1718,7 @@ version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -1715,7 +1761,7 @@ dependencies = [
"hex 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ipnetwork 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", "ipnetwork 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"md-5 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "md-5 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1799,7 +1845,7 @@ version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)",
"remove_dir_all 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "remove_dir_all 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1853,7 +1899,7 @@ name = "time"
version = "0.1.43" version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -1872,7 +1918,7 @@ dependencies = [
"futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)",
"mio-named-pipes 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "mio-named-pipes 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1956,13 +2002,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "tracing" name = "tracing"
version = "0.1.17" version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing-attributes 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "tracing-attributes 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tracing-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -1977,7 +2023,7 @@ dependencies = [
[[package]] [[package]]
name = "tracing-core" name = "tracing-core"
version = "0.1.11" version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1989,7 +2035,7 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"pin-project 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "tracing 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -1999,7 +2045,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tracing-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -2008,12 +2054,12 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tracing-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "tracing-subscriber" name = "tracing-subscriber"
version = "0.2.9" version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2025,7 +2071,7 @@ dependencies = [
"serde_json 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)",
"sharded-slab 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "sharded-slab 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tracing-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing-log 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tracing-log 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tracing-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -2212,7 +2258,7 @@ dependencies = [
"tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-tungstenite 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tungstenite 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "tracing 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing-futures 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "tracing-futures 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"urlencoding 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "urlencoding 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -2270,6 +2316,7 @@ dependencies = [
[metadata] [metadata]
"checksum adler 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" "checksum adler 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
"checksum ahash 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6f33b5018f120946c1dcf279194f238a9f146725593ead1c08fa47ff22b0b5d3"
"checksum aho-corasick 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)" = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86" "checksum aho-corasick 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)" = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86"
"checksum alloc-no-stdlib 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5192ec435945d87bc2f70992b4d818154b5feede43c09fb7592146374eac90a6" "checksum alloc-no-stdlib 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5192ec435945d87bc2f70992b4d818154b5feede43c09fb7592146374eac90a6"
"checksum alloc-stdlib 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "697ed7edc0f1711de49ce108c541623a0af97c6c60b2f6e2b65229847ac843c2" "checksum alloc-stdlib 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "697ed7edc0f1711de49ce108c541623a0af97c6c60b2f6e2b65229847ac843c2"
@ -2304,6 +2351,8 @@ dependencies = [
"checksum clap_derive 3.0.0-beta.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fb51c9e75b94452505acd21d929323f5a5c6c4735a852adbd39ef5fb1b014f30" "checksum clap_derive 3.0.0-beta.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fb51c9e75b94452505acd21d929323f5a5c6c4735a852adbd39ef5fb1b014f30"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum cloudabi 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467" "checksum cloudabi 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467"
"checksum const-random 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "2f1af9ac737b2dd2d577701e59fd09ba34822f6f2ebdb30a7647405d9e55e16a"
"checksum const-random-macro 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "25e4c606eb459dd29f7c57b2e0879f2b6f14ee130918c2b78ccb58a9624e6c7a"
"checksum core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" "checksum core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171"
"checksum core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" "checksum core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac"
"checksum cpuid-bool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" "checksum cpuid-bool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
@ -2338,6 +2387,7 @@ dependencies = [
"checksum generic-array 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)" = "60fb4bb6bba52f78a471264d9a3b7d026cc0af47b22cd2cffbc0b787ca003e63" "checksum generic-array 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)" = "60fb4bb6bba52f78a471264d9a3b7d026cc0af47b22cd2cffbc0b787ca003e63"
"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" "checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
"checksum h2 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "993f9e0baeed60001cf565546b0d3dbe6a6ad23f2bd31644a133c641eccf6d53" "checksum h2 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "993f9e0baeed60001cf565546b0d3dbe6a6ad23f2bd31644a133c641eccf6d53"
"checksum hashbrown 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8e6073d0ca812575946eb5f35ff68dbe519907b25c42530389ff946dc84c6ead"
"checksum hashbrown 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "34f595585f103464d8d2f6e9864682d74c1601fed5e07d62b1c9058dba8246fb" "checksum hashbrown 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "34f595585f103464d8d2f6e9864682d74c1601fed5e07d62b1c9058dba8246fb"
"checksum headers 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ed18eb2459bf1a09ad2d6b1547840c3e5e62882fa09b9a6a20b1de8e3228848f" "checksum headers 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ed18eb2459bf1a09ad2d6b1547840c3e5e62882fa09b9a6a20b1de8e3228848f"
"checksum headers-core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" "checksum headers-core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429"
@ -2360,11 +2410,12 @@ dependencies = [
"checksum itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" "checksum itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
"checksum libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)" = "bd7d4bd64732af4bf3a67f367c27df8520ad7e230c5817b8ff485864d80242b9" "checksum libc 0.2.74 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f02823cf78b754822df5f7f268fb59822e7296276d3e069d8e8cb26a14bd10"
"checksum listenfd 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "492158e732f2e2de81c592f0a2427e57e12cd3d59877378fe7af624b6bbe0ca1" "checksum listenfd 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "492158e732f2e2de81c592f0a2427e57e12cd3d59877378fe7af624b6bbe0ca1"
"checksum lock_api 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "28247cc5a5be2f05fbcd76dd0cf2c7d3b5400cb978a28042abcd4fa0b3f8261c" "checksum lock_api 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "28247cc5a5be2f05fbcd76dd0cf2c7d3b5400cb978a28042abcd4fa0b3f8261c"
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
"checksum log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" "checksum log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
"checksum lru 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "35c456c123957de3a220cd03786e0d86aa542a88b46029973b542f426da6ef34"
"checksum maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" "checksum maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
"checksum matchers 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" "checksum matchers 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1"
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
@ -2489,13 +2540,13 @@ dependencies = [
"checksum tokio-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" "checksum tokio-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499"
"checksum toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" "checksum toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a"
"checksum tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860" "checksum tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860"
"checksum tracing 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "dbdf4ccd1652592b01286a5dbe1e2a77d78afaa34beadd9872a5f7396f92aaa9" "checksum tracing 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "f0aae59226cf195d8e74d4b34beae1859257efb4e5fed3f147d2dc2c7d372178"
"checksum tracing-attributes 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f0693bf8d6f2bf22c690fc61a9d21ac69efdbb894a17ed596b9af0f01e64b84b" "checksum tracing-attributes 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f0693bf8d6f2bf22c690fc61a9d21ac69efdbb894a17ed596b9af0f01e64b84b"
"checksum tracing-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "94ae75f0d28ae10786f3b1895c55fe72e79928fd5ccdebb5438c75e93fec178f" "checksum tracing-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "b2734b5a028fa697686f16c6d18c2c6a3c7e41513f9a213abb6754c4acb3c8d7"
"checksum tracing-futures 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ab7bb6f14721aa00656086e9335d363c5c8747bae02ebe32ea2c7dece5689b4c" "checksum tracing-futures 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ab7bb6f14721aa00656086e9335d363c5c8747bae02ebe32ea2c7dece5689b4c"
"checksum tracing-log 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e0f8c7178e13481ff6765bd169b33e8d554c5d2bbede5e32c356194be02b9b9" "checksum tracing-log 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e0f8c7178e13481ff6765bd169b33e8d554c5d2bbede5e32c356194be02b9b9"
"checksum tracing-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6ccba2f8f16e0ed268fc765d9b7ff22e965e7185d32f8f1ec8294fe17d86e79" "checksum tracing-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6ccba2f8f16e0ed268fc765d9b7ff22e965e7185d32f8f1ec8294fe17d86e79"
"checksum tracing-subscriber 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e4f5dd7095c2481b7b3cbed71c8de53085fb3542bc3c2b4c73cba43e8f11c7ba" "checksum tracing-subscriber 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b33f8b2ef2ab0c3778c12646d9c42a24f7772bee4cdafc72199644a9f58fdc"
"checksum try-lock 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" "checksum try-lock 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
"checksum tungstenite 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cfea31758bf674f990918962e8e5f07071a3161bd7c4138ed23e416e1ac4264e" "checksum tungstenite 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cfea31758bf674f990918962e8e5f07071a3161bd7c4138ed23e416e1ac4264e"
"checksum twoway 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1" "checksum twoway 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1"

View File

@ -13,7 +13,7 @@ dotenv = "0.15"
http-api-problem = { version = "0.17", features = ["with-warp"] } http-api-problem = { version = "0.17", features = ["with-warp"] }
hyper = "0.13" hyper = "0.13"
listenfd = "0.3" listenfd = "0.3"
tokio = { version = "0.2", features = ["macros"] } tokio = { version = "0.2", features = ["macros", "rt-threaded", "sync"] }
sqlx = { version = "0.3", default-features = false, features = [ "runtime-tokio", "macros", "postgres", "chrono", "uuid", "ipnetwork", "json" ] } sqlx = { version = "0.3", default-features = false, features = [ "runtime-tokio", "macros", "postgres", "chrono", "uuid", "ipnetwork", "json" ] }
warp = { version = "0.2", features = ["compression"] } warp = { version = "0.2", features = ["compression"] }
refinery = { version = "0.3.0", features = [ "tokio-postgres", "tokio" ] } refinery = { version = "0.3.0", features = [ "tokio-postgres", "tokio" ] }
@ -28,3 +28,6 @@ async-trait = "0.1"
tracing = "0.1" tracing = "0.1"
tracing-subscriber = "0.2" tracing-subscriber = "0.2"
tracing-futures = "0.2" tracing-futures = "0.2"
lru = "0.5"
http = "0.2"
bytes = "0.5"

133
src/caches/cache.rs Normal file
View File

@ -0,0 +1,133 @@
use anyhow::Result;
use lru::LruCache;
use std::fmt::Debug;
use std::future::Future;
use std::hash::Hash;
use std::sync::Arc;
use tokio::sync::Mutex;
use tracing::debug;
use warp::{Rejection, Reply};
use super::CachedResponse;
use crate::problem::{reject_anyhow, unpack_problem};
#[derive(Debug, Clone)]
pub struct Cache<K, V>
where
K: Eq + Hash + Debug,
V: Clone,
{
pub name: String,
pub lru_mutex: Arc<Mutex<LruCache<K, V>>>,
pub log_keys: bool,
}
impl<K, V> Cache<K, V>
where
K: Eq + Hash + Debug,
V: Clone,
{
pub fn new(name: &str, capacity: usize) -> Self {
Cache {
name: name.to_string(),
lru_mutex: Arc::new(Mutex::new(LruCache::new(capacity))),
log_keys: true,
}
}
pub fn log_keys(mut self, value: bool) -> Self {
self.log_keys = value;
self
}
pub fn log_with_key(&self, key: &K, message: &str) {
if self.log_keys {
debug!(cache = %self.name, key = ?key, message);
} else {
debug!(cache = %self.name, message);
}
}
pub async fn get<G, F>(&self, key: K, getter: G) -> Result<V>
where
G: Fn() -> F,
F: Future<Output = Result<V>>,
{
let mut guard = self.lru_mutex.lock().await;
if let Some(value) = guard.get(&key) {
self.log_with_key(&key, "get: hit");
return Ok(value.clone());
}
drop(guard);
self.log_with_key(&key, "get: miss");
let value = getter().await?;
let mut guard = self.lru_mutex.lock().await;
guard.put(key, value.clone());
Ok(value)
}
pub async fn delete(&self, key: K) -> Result<Option<V>> {
let mut guard = self.lru_mutex.lock().await;
let value = guard.pop(&key);
self.log_with_key(&key, "delete");
Ok(value)
}
pub async fn clear(&self) {
let mut guard = self.lru_mutex.lock().await;
guard.clear();
debug!(cache = %self.name, "cache clear");
}
}
impl<K> Cache<K, CachedResponse>
where
K: Eq + Hash + Debug,
{
pub async fn get_response<G, F, R>(
&self,
key: K,
getter: G,
) -> Result<CachedResponse, Rejection>
where
G: Fn() -> F,
F: Future<Output = Result<R>>,
R: Reply,
{
let mut guard = self.lru_mutex.lock().await;
if let Some(value) = guard.get(&key) {
self.log_with_key(&key, "get_response: hit");
return Ok(value.clone());
}
drop(guard);
self.log_with_key(&key, "get_response: miss");
let reply = getter().await.map_err(reject_anyhow);
let cached_response = match reply {
Ok(reply) => CachedResponse::from_reply(reply)
.await
.map_err(reject_anyhow)?,
Err(rejection) => {
let reply = unpack_problem(rejection).await?;
CachedResponse::from_reply(reply)
.await
.map_err(reject_anyhow)?
}
};
let mut guard = self.lru_mutex.lock().await;
guard.put(key, cached_response.clone());
Ok(cached_response)
}
pub async fn delete_response(&self, key: K) -> Result<Option<CachedResponse>> {
let mut guard = self.lru_mutex.lock().await;
let cached_response = guard.pop(&key);
self.log_with_key(&key, "delete_response");
Ok(cached_response)
}
}

View File

@ -0,0 +1,46 @@
use anyhow::Result;
use http::{HeaderMap, HeaderValue, Response, StatusCode, Version};
use hyper::body::{to_bytes, Body, Bytes};
use warp::Reply;
#[derive(Debug, Clone)]
pub struct CachedResponse {
pub status: StatusCode,
pub version: Version,
pub headers: HeaderMap<HeaderValue>,
pub body: Bytes,
}
impl CachedResponse {
pub async fn from_reply<T>(reply: T) -> Result<Self>
where
T: Reply,
{
let mut response = reply.into_response();
Ok(CachedResponse {
status: response.status(),
version: response.version(),
headers: response.headers().clone(),
body: to_bytes(response.body_mut()).await?,
})
}
}
impl Reply for CachedResponse {
fn into_response(self) -> warp::reply::Response {
match Response::builder()
.status(self.status)
.version(self.version)
.body(Body::from(self.body))
{
Ok(mut response) => {
let headers = response.headers_mut();
for (header, value) in self.headers.iter() {
headers.insert(header, value.clone());
}
response
}
Err(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
}
}
}

35
src/caches/mod.rs Normal file
View File

@ -0,0 +1,35 @@
use std::fmt::Debug;
use uuid::Uuid;
use crate::models::ListParams;
mod cache;
mod cached_response;
pub use cache::Cache;
pub use cached_response::CachedResponse;
#[derive(Debug, Clone)]
pub struct Caches {
pub owner_ids_by_api_key: Cache<Uuid, i32>,
pub shop: Cache<i32, CachedResponse>,
pub owner: Cache<i32, CachedResponse>,
pub interior_ref_list: Cache<i32, CachedResponse>,
pub list_shops: Cache<ListParams, CachedResponse>,
pub list_owners: Cache<ListParams, CachedResponse>,
pub list_interior_ref_lists: Cache<ListParams, CachedResponse>,
}
impl Caches {
pub fn initialize() -> Self {
Caches {
owner_ids_by_api_key: Cache::new("owner_ids_by_api_key", 100).log_keys(false),
shop: Cache::new("shop", 100),
owner: Cache::new("owner", 100),
interior_ref_list: Cache::new("interior_ref_list", 100),
list_shops: Cache::new("list_shops", 100),
list_owners: Cache::new("list_owners", 100),
list_interior_ref_lists: Cache::new("list_interior_ref_lists", 100),
}
}
}

View File

@ -45,7 +45,8 @@ pub fn get_shop(env: Environment) -> impl Filter<Extract = impl Reply, Error = R
pub fn create_shop( pub fn create_shop(
env: Environment, env: Environment,
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone { ) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
warp::post() warp::path::end()
.and(warp::post())
.and(json_body::<Shop>()) .and(json_body::<Shop>())
.and(with_env(env)) .and(with_env(env))
.and_then(handlers::create_shop) .and_then(handlers::create_shop)
@ -64,7 +65,8 @@ pub fn delete_shop(
pub fn list_shops( pub fn list_shops(
env: Environment, env: Environment,
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone { ) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
warp::get() warp::path::end()
.and(warp::get())
.and(warp::query::<ListParams>()) .and(warp::query::<ListParams>())
.and(with_env(env)) .and(with_env(env))
.and_then(handlers::list_shops) .and_then(handlers::list_shops)
@ -80,7 +82,8 @@ pub fn get_owner(env: Environment) -> impl Filter<Extract = impl Reply, Error =
pub fn create_owner( pub fn create_owner(
env: Environment, env: Environment,
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone { ) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
warp::post() warp::path::end()
.and(warp::post())
.and(json_body::<Owner>()) .and(json_body::<Owner>())
.and(warp::addr::remote()) .and(warp::addr::remote())
.and(with_env(env)) .and(with_env(env))
@ -100,7 +103,8 @@ pub fn delete_owner(
pub fn list_owners( pub fn list_owners(
env: Environment, env: Environment,
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone { ) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
warp::get() warp::path::end()
.and(warp::get())
.and(warp::query::<ListParams>()) .and(warp::query::<ListParams>())
.and(with_env(env)) .and(with_env(env))
.and_then(handlers::list_owners) .and_then(handlers::list_owners)
@ -118,7 +122,8 @@ pub fn get_interior_ref_list(
pub fn create_interior_ref_list( pub fn create_interior_ref_list(
env: Environment, env: Environment,
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone { ) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
warp::post() warp::path::end()
.and(warp::post())
.and(json_body::<InteriorRefList>()) .and(json_body::<InteriorRefList>())
.and(with_env(env)) .and(with_env(env))
.and_then(handlers::create_interior_ref_list) .and_then(handlers::create_interior_ref_list)
@ -137,7 +142,8 @@ pub fn delete_interior_ref_list(
pub fn list_interior_ref_lists( pub fn list_interior_ref_lists(
env: Environment, env: Environment,
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone { ) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
warp::get() warp::path::end()
.and(warp::get())
.and(warp::query::<ListParams>()) .and(warp::query::<ListParams>())
.and(with_env(env)) .and(with_env(env))
.and_then(handlers::list_interior_ref_lists) .and_then(handlers::list_interior_ref_lists)

View File

@ -2,6 +2,7 @@ use anyhow::{anyhow, Result};
use ipnetwork::IpNetwork; use ipnetwork::IpNetwork;
use sqlx::postgres::PgPool; use sqlx::postgres::PgPool;
use std::net::SocketAddr; use std::net::SocketAddr;
use tracing::instrument;
use uuid::Uuid; use uuid::Uuid;
use warp::http::StatusCode; use warp::http::StatusCode;
use warp::reply::{json, with_header, with_status}; use warp::reply::{json, with_header, with_status};
@ -10,51 +11,73 @@ use warp::{Rejection, Reply};
use super::models::{InteriorRefList, ListParams, Model, Owner, Shop}; use super::models::{InteriorRefList, ListParams, Model, Owner, Shop};
use super::problem::{forbidden_no_api_key, forbidden_no_owner, reject_anyhow}; use super::problem::{forbidden_no_api_key, forbidden_no_owner, reject_anyhow};
use super::Environment; use super::Environment;
use crate::caches::Cache;
pub async fn authenticate(api_key: Option<Uuid>, db: &PgPool) -> Result<i32> { #[instrument(level = "debug", skip(db, cache, api_key))]
pub async fn authenticate(
db: &PgPool,
cache: &Cache<Uuid, i32>,
api_key: Option<Uuid>,
) -> Result<i32> {
if let Some(api_key) = api_key { if let Some(api_key) = api_key {
Ok( cache
sqlx::query!("SELECT id FROM owners WHERE api_key = $1", api_key) .get(api_key, || async {
.fetch_one(db) Ok(
.await sqlx::query!("SELECT id FROM owners WHERE api_key = $1", api_key)
.map_err(|error| { .fetch_one(db)
if let sqlx::Error::RowNotFound = error { .await
return forbidden_no_owner(); .map_err(|error| {
} if let sqlx::Error::RowNotFound = error {
anyhow!(error) return forbidden_no_owner();
})? }
.id, anyhow!(error)
) })?
.id,
)
})
.await
} else { } else {
// TODO: this should be 401 status instead
Err(forbidden_no_api_key()) Err(forbidden_no_api_key())
} }
} }
pub async fn get_shop(id: i32, env: Environment) -> Result<impl Reply, Rejection> { pub async fn get_shop(id: i32, env: Environment) -> Result<impl Reply, Rejection> {
let shop = Shop::get(&env.db, id).await.map_err(reject_anyhow)?; env.caches
let reply = json(&shop); .shop
let reply = with_status(reply, StatusCode::OK); .get_response(id, || async {
Ok(reply) let shop = Shop::get(&env.db, id).await?;
let reply = json(&shop);
let reply = with_status(reply, StatusCode::OK);
Ok(reply)
})
.await
} }
pub async fn list_shops( pub async fn list_shops(
list_params: ListParams, list_params: ListParams,
env: Environment, env: Environment,
) -> Result<impl Reply, Rejection> { ) -> Result<impl Reply, Rejection> {
let shops = Shop::list(&env.db, list_params) env.caches
.list_shops
.get_response(list_params.clone(), || async {
let shops = Shop::list(&env.db, &list_params).await?;
let reply = json(&shops);
let reply = with_status(reply, StatusCode::OK);
Ok(reply)
})
.await .await
.map_err(reject_anyhow)?;
let reply = json(&shops);
let reply = with_status(reply, StatusCode::OK);
Ok(reply)
} }
pub async fn create_shop(shop: Shop, env: Environment) -> Result<impl Reply, Rejection> { pub async fn create_shop(shop: Shop, env: Environment) -> Result<impl Reply, Rejection> {
// TODO: authenticate
// TODO: return 400 error with message if unique key is violated
let saved_shop = shop.save(&env.db).await.map_err(reject_anyhow)?; let saved_shop = shop.save(&env.db).await.map_err(reject_anyhow)?;
let url = saved_shop.url(&env.api_url).map_err(reject_anyhow)?; let url = saved_shop.url(&env.api_url).map_err(reject_anyhow)?;
let reply = json(&saved_shop); let reply = json(&saved_shop);
let reply = with_header(reply, "Location", url.as_str()); let reply = with_header(reply, "Location", url.as_str());
let reply = with_status(reply, StatusCode::CREATED); let reply = with_status(reply, StatusCode::CREATED);
env.caches.list_shops.clear().await;
Ok(reply) Ok(reply)
} }
@ -63,33 +86,46 @@ pub async fn delete_shop(
api_key: Option<Uuid>, api_key: Option<Uuid>,
env: Environment, env: Environment,
) -> Result<impl Reply, Rejection> { ) -> Result<impl Reply, Rejection> {
let owner_id = authenticate(api_key, &env.db) let owner_id = authenticate(&env.db, &env.caches.owner_ids_by_api_key, api_key)
.await .await
.map_err(reject_anyhow)?; .map_err(reject_anyhow)?;
dbg!(owner_id);
Shop::delete(&env.db, owner_id, id) Shop::delete(&env.db, owner_id, id)
.await .await
.map_err(reject_anyhow)?; .map_err(reject_anyhow)?;
env.caches
.shop
.delete_response(id)
.await
.map_err(reject_anyhow)?;
env.caches.list_shops.clear().await;
Ok(StatusCode::NO_CONTENT) Ok(StatusCode::NO_CONTENT)
} }
pub async fn get_owner(id: i32, env: Environment) -> Result<impl Reply, Rejection> { pub async fn get_owner(id: i32, env: Environment) -> Result<impl Reply, Rejection> {
let owner = Owner::get(&env.db, id).await.map_err(reject_anyhow)?; env.caches
let reply = json(&owner); .owner
let reply = with_status(reply, StatusCode::OK); .get_response(id, || async {
Ok(reply) let owner = Owner::get(&env.db, id).await?;
let reply = json(&owner);
let reply = with_status(reply, StatusCode::OK);
Ok(reply)
})
.await
} }
pub async fn list_owners( pub async fn list_owners(
list_params: ListParams, list_params: ListParams,
env: Environment, env: Environment,
) -> Result<impl Reply, Rejection> { ) -> Result<impl Reply, Rejection> {
let owners = Owner::list(&env.db, list_params) env.caches
.list_owners
.get_response(list_params.clone(), || async {
let owners = Owner::list(&env.db, &list_params).await?;
let reply = json(&owners);
let reply = with_status(reply, StatusCode::OK);
Ok(reply)
})
.await .await
.map_err(reject_anyhow)?;
let reply = json(&owners);
let reply = with_status(reply, StatusCode::OK);
Ok(reply)
} }
pub async fn create_owner( pub async fn create_owner(
@ -97,6 +133,7 @@ pub async fn create_owner(
remote_addr: Option<SocketAddr>, remote_addr: Option<SocketAddr>,
env: Environment, env: Environment,
) -> Result<impl Reply, Rejection> { ) -> Result<impl Reply, Rejection> {
// TODO: authenticate and get api_key from header
let owner_with_ip = match remote_addr { let owner_with_ip = match remote_addr {
Some(addr) => Owner { Some(addr) => Owner {
ip_address: Some(IpNetwork::from(addr.ip())), ip_address: Some(IpNetwork::from(addr.ip())),
@ -109,6 +146,7 @@ pub async fn create_owner(
let reply = json(&saved_owner); let reply = json(&saved_owner);
let reply = with_header(reply, "Location", url.as_str()); let reply = with_header(reply, "Location", url.as_str());
let reply = with_status(reply, StatusCode::CREATED); let reply = with_status(reply, StatusCode::CREATED);
env.caches.list_owners.clear().await;
Ok(reply) Ok(reply)
} }
@ -117,41 +155,58 @@ pub async fn delete_owner(
api_key: Option<Uuid>, api_key: Option<Uuid>,
env: Environment, env: Environment,
) -> Result<impl Reply, Rejection> { ) -> Result<impl Reply, Rejection> {
let owner_id = authenticate(api_key, &env.db) let owner_id = authenticate(&env.db, &env.caches.owner_ids_by_api_key, api_key)
.await .await
.map_err(reject_anyhow)?; .map_err(reject_anyhow)?;
dbg!(owner_id);
Owner::delete(&env.db, owner_id, id) Owner::delete(&env.db, owner_id, id)
.await .await
.map_err(reject_anyhow)?; .map_err(reject_anyhow)?;
env.caches
.owner
.delete_response(id)
.await
.map_err(reject_anyhow)?;
env.caches
.owner_ids_by_api_key
.delete(api_key.expect("api-key has been validated during authenticate"))
.await
.map_err(reject_anyhow)?;
env.caches.list_owners.clear().await;
Ok(StatusCode::NO_CONTENT) Ok(StatusCode::NO_CONTENT)
} }
pub async fn get_interior_ref_list(id: i32, env: Environment) -> Result<impl Reply, Rejection> { pub async fn get_interior_ref_list(id: i32, env: Environment) -> Result<impl Reply, Rejection> {
let interior_ref_list = InteriorRefList::get(&env.db, id) env.caches
.interior_ref_list
.get_response(id, || async {
let interior_ref_list = InteriorRefList::get(&env.db, id).await?;
let reply = json(&interior_ref_list);
let reply = with_status(reply, StatusCode::OK);
Ok(reply)
})
.await .await
.map_err(reject_anyhow)?;
let reply = json(&interior_ref_list);
let reply = with_status(reply, StatusCode::OK);
Ok(reply)
} }
pub async fn list_interior_ref_lists( pub async fn list_interior_ref_lists(
list_params: ListParams, list_params: ListParams,
env: Environment, env: Environment,
) -> Result<impl Reply, Rejection> { ) -> Result<impl Reply, Rejection> {
let interior_ref_lists = InteriorRefList::list(&env.db, list_params) env.caches
.list_interior_ref_lists
.get_response(list_params.clone(), || async {
let interior_ref_lists = InteriorRefList::list(&env.db, &list_params).await?;
let reply = json(&interior_ref_lists);
let reply = with_status(reply, StatusCode::OK);
Ok(reply)
})
.await .await
.map_err(reject_anyhow)?;
let reply = json(&interior_ref_lists);
let reply = with_status(reply, StatusCode::OK);
Ok(reply)
} }
pub async fn create_interior_ref_list( pub async fn create_interior_ref_list(
interior_ref_list: InteriorRefList, interior_ref_list: InteriorRefList,
env: Environment, env: Environment,
) -> Result<impl Reply, Rejection> { ) -> Result<impl Reply, Rejection> {
// TODO: authenticate
let saved_interior_ref_list = interior_ref_list let saved_interior_ref_list = interior_ref_list
.save(&env.db) .save(&env.db)
.await .await
@ -162,6 +217,7 @@ pub async fn create_interior_ref_list(
let reply = json(&saved_interior_ref_list); let reply = json(&saved_interior_ref_list);
let reply = with_header(reply, "Location", url.as_str()); let reply = with_header(reply, "Location", url.as_str());
let reply = with_status(reply, StatusCode::CREATED); let reply = with_status(reply, StatusCode::CREATED);
env.caches.list_interior_ref_lists.clear().await;
Ok(reply) Ok(reply)
} }
@ -170,12 +226,17 @@ pub async fn delete_interior_ref_list(
api_key: Option<Uuid>, api_key: Option<Uuid>,
env: Environment, env: Environment,
) -> Result<impl Reply, Rejection> { ) -> Result<impl Reply, Rejection> {
let owner_id = authenticate(api_key, &env.db) let owner_id = authenticate(&env.db, &env.caches.owner_ids_by_api_key, api_key)
.await .await
.map_err(reject_anyhow)?; .map_err(reject_anyhow)?;
dbg!(owner_id);
InteriorRefList::delete(&env.db, owner_id, id) InteriorRefList::delete(&env.db, owner_id, id)
.await .await
.map_err(reject_anyhow)?; .map_err(reject_anyhow)?;
env.caches
.interior_ref_list
.delete_response(id)
.await
.map_err(reject_anyhow)?;
env.caches.list_interior_ref_lists.clear().await;
Ok(StatusCode::NO_CONTENT) Ok(StatusCode::NO_CONTENT)
} }

View File

@ -12,12 +12,15 @@ use tracing_subscriber::fmt::format::FmtSpan;
use url::Url; use url::Url;
use warp::Filter; use warp::Filter;
mod caches;
mod db; mod db;
mod filters; mod filters;
mod handlers; mod handlers;
mod models; mod models;
mod problem; mod problem;
use caches::Caches;
#[derive(Clap)] #[derive(Clap)]
#[clap(version = "0.1.0", author = "Tyler Hallada <tyler@hallada.net>")] #[clap(version = "0.1.0", author = "Tyler Hallada <tyler@hallada.net>")]
struct Opts { struct Opts {
@ -28,6 +31,7 @@ struct Opts {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Environment { pub struct Environment {
pub db: PgPool, pub db: PgPool,
pub caches: Caches,
pub api_url: Url, pub api_url: Url,
} }
@ -38,6 +42,7 @@ impl Environment {
.max_size(5) .max_size(5)
.build(&env::var("DATABASE_URL")?) .build(&env::var("DATABASE_URL")?)
.await?, .await?,
caches: Caches::initialize(),
api_url, api_url,
}) })
} }

View File

@ -1,4 +1,4 @@
use anyhow::Result; use anyhow::{Error, Result};
use async_trait::async_trait; use async_trait::async_trait;
use chrono::prelude::*; use chrono::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -50,11 +50,10 @@ impl Model for InteriorRefList {
#[instrument(level = "debug", skip(db))] #[instrument(level = "debug", skip(db))]
async fn get(db: &PgPool, id: i32) -> Result<Self> { async fn get(db: &PgPool, id: i32) -> Result<Self> {
Ok( sqlx::query_as_unchecked!(Self, "SELECT * FROM interior_ref_lists WHERE id = $1", id)
sqlx::query_as_unchecked!(Self, "SELECT * FROM interior_ref_lists WHERE id = $1", id) .fetch_one(db)
.fetch_one(db) .await
.await?, .map_err(Error::new)
)
} }
#[instrument(level = "debug", skip(self, db))] #[instrument(level = "debug", skip(self, db))]
@ -95,7 +94,7 @@ impl Model for InteriorRefList {
} }
#[instrument(level = "debug", skip(db))] #[instrument(level = "debug", skip(db))]
async fn list(db: &PgPool, list_params: ListParams) -> Result<Vec<Self>> { async fn list(db: &PgPool, list_params: &ListParams) -> Result<Vec<Self>> {
let result = if let Some(order_by) = list_params.get_order_by() { let result = if let Some(order_by) = list_params.get_order_by() {
sqlx::query_as_unchecked!( sqlx::query_as_unchecked!(
Self, Self,

View File

@ -1,5 +1,6 @@
use serde::Deserialize; use serde::Deserialize;
use std::fmt; use std::fmt;
use std::hash::Hash;
pub mod interior_ref_list; pub mod interior_ref_list;
pub mod model; pub mod model;
@ -11,7 +12,7 @@ pub use model::Model;
pub use owner::Owner; pub use owner::Owner;
pub use shop::Shop; pub use shop::Shop;
#[derive(Debug, Deserialize)] #[derive(Debug, Eq, PartialEq, Hash, Clone, Deserialize)]
pub enum Order { pub enum Order {
Asc, Asc,
Desc, Desc,
@ -30,7 +31,7 @@ impl fmt::Display for Order {
} }
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Eq, PartialEq, Hash, Clone, Deserialize)]
pub struct ListParams { pub struct ListParams {
limit: Option<i64>, limit: Option<i64>,
offset: Option<i64>, offset: Option<i64>,

View File

@ -25,5 +25,5 @@ where
async fn get(db: &PgPool, id: i32) -> Result<Self>; async fn get(db: &PgPool, id: i32) -> Result<Self>;
async fn save(self, db: &PgPool) -> Result<Self>; async fn save(self, db: &PgPool) -> Result<Self>;
async fn delete(db: &PgPool, owner_id: i32, id: i32) -> Result<u64>; async fn delete(db: &PgPool, owner_id: i32, id: i32) -> Result<u64>;
async fn list(db: &PgPool, list_params: ListParams) -> Result<Vec<Self>>; async fn list(db: &PgPool, list_params: &ListParams) -> Result<Vec<Self>>;
} }

View File

@ -1,4 +1,4 @@
use anyhow::Result; use anyhow::{Error, Result};
use async_trait::async_trait; use async_trait::async_trait;
use chrono::prelude::*; use chrono::prelude::*;
use ipnetwork::IpNetwork; use ipnetwork::IpNetwork;
@ -34,11 +34,10 @@ impl Model for Owner {
#[instrument(level = "debug", skip(db))] #[instrument(level = "debug", skip(db))]
async fn get(db: &PgPool, id: i32) -> Result<Self> { async fn get(db: &PgPool, id: i32) -> Result<Self> {
Ok( sqlx::query_as!(Self, "SELECT * FROM owners WHERE id = $1", id)
sqlx::query_as!(Self, "SELECT * FROM owners WHERE id = $1", id) .fetch_one(db)
.fetch_one(db) .await
.await?, .map_err(Error::new)
)
} }
#[instrument(level = "debug", skip(db))] #[instrument(level = "debug", skip(db))]
@ -73,7 +72,7 @@ impl Model for Owner {
} }
#[instrument(level = "debug", skip(db))] #[instrument(level = "debug", skip(db))]
async fn list(db: &PgPool, list_params: ListParams) -> Result<Vec<Self>> { async fn list(db: &PgPool, list_params: &ListParams) -> Result<Vec<Self>> {
let result = if let Some(order_by) = list_params.get_order_by() { let result = if let Some(order_by) = list_params.get_order_by() {
sqlx::query_as!( sqlx::query_as!(
Self, Self,

View File

@ -1,4 +1,4 @@
use anyhow::Result; use anyhow::{Error, Result};
use async_trait::async_trait; use async_trait::async_trait;
use chrono::prelude::*; use chrono::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -35,11 +35,10 @@ impl Model for Shop {
#[instrument(level = "debug", skip(db))] #[instrument(level = "debug", skip(db))]
async fn get(db: &PgPool, id: i32) -> Result<Self> { async fn get(db: &PgPool, id: i32) -> Result<Self> {
Ok( sqlx::query_as!(Self, "SELECT * FROM shops WHERE id = $1", id)
sqlx::query_as!(Self, "SELECT * FROM shops WHERE id = $1", id) .fetch_one(db)
.fetch_one(db) .await
.await?, .map_err(Error::new)
)
} }
#[instrument(level = "debug", skip(db))] #[instrument(level = "debug", skip(db))]
@ -78,7 +77,7 @@ impl Model for Shop {
} }
#[instrument(level = "debug", skip(db))] #[instrument(level = "debug", skip(db))]
async fn list(db: &PgPool, list_params: ListParams) -> Result<Vec<Self>> { async fn list(db: &PgPool, list_params: &ListParams) -> Result<Vec<Self>> {
let result = if let Some(order_by) = list_params.get_order_by() { let result = if let Some(order_by) = list_params.get_order_by() {
sqlx::query_as!( sqlx::query_as!(
Self, Self,

9
test_data/shop2.json Normal file
View File

@ -0,0 +1,9 @@
{
"name": "Test Shop",
"owner_id": 2,
"description": "for testing",
"is_not_sell_buy": true,
"sell_buy_list_id": 1,
"vendor_id": 1,
"vendor_gold": 0
}