diff --git a/poetry.lock b/poetry.lock index f4d4ceb..eb89ce1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -77,60 +77,58 @@ test = ["hypothesis", "pytest", "readme-renderer"] [[package]] name = "meta-memcache-socket" -version = "0.1.0" +version = "0.1.1" description = "" optional = false python-versions = ">=3.7" files = [ - {file = "meta_memcache_socket-0.1.0-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:276ff6496b1bd2697c01bc7532bf212fd7bed53bca7f9860b097fefd44f0f255"}, - {file = "meta_memcache_socket-0.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:85c877cdd9568377111ac8e45c3b1d3ac88fd3c7d1dbce769bc598e2917a8d13"}, - {file = "meta_memcache_socket-0.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50939f7225c0a1849fab1ba08441f5dfaea66e08520fbc79725df5da75ea11f9"}, - {file = "meta_memcache_socket-0.1.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:13783808b431c149e0f4de7bdd631df6004a971d1717189b93796b63835fe108"}, - {file = "meta_memcache_socket-0.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8a8c2e62c7afdb4604a84638b17074266e5f285ca0fc9524af1ab81e13ea520"}, - {file = "meta_memcache_socket-0.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:77031dfd683856d9f3e5461d3b5234b6df008d45dbc6a85d0b9a94b55db2d7c8"}, - {file = "meta_memcache_socket-0.1.0-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:9a771144b6db23570fdf0f1008aa6017e65464e720e05038c8479a8146e2be19"}, - {file = "meta_memcache_socket-0.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4b262cb9aa55424e840385c43af84b22bb16d0f29e8e15ce1ddf6afcf567b5bc"}, - {file = "meta_memcache_socket-0.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7429efaace51c28adc876f16994930d9c1a0507d1a3c4b2e0ee0a7070f22eba8"}, - {file = "meta_memcache_socket-0.1.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:976cd618023d78169b41b9cd9ae3bccccd185205241b5146a3e8859edb458f27"}, - {file = "meta_memcache_socket-0.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc3c87c581ff04902bce2a08c67e646142f33da4d0a2460d74ab0c2701a7cc09"}, - {file = "meta_memcache_socket-0.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:98efeca606829f4f5bd7add7b1c698a3a6da2565df2d239295d162484f334e04"}, - {file = "meta_memcache_socket-0.1.0-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:fe050b98fcdef5c8b1c0c993f69397220b0a605884c2439be6fd4cb8fd4274f0"}, - {file = "meta_memcache_socket-0.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9b2b93aa16620c224735d162e2cb9b5623a3c46c43a7a33f4c1c6fcd1df1d55e"}, - {file = "meta_memcache_socket-0.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77bb692a2522c70ca57bd393eb664148957982a607b1bc07cc18d4c733c504d5"}, - {file = "meta_memcache_socket-0.1.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:55f92f2bd27a3bb96fb0d1e0ab34196ff3929f84656852a5ddaac578fbf7c1c8"}, - {file = "meta_memcache_socket-0.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:682007ae78f1eaeaa3eaabb4db956d4b6950d34737dd4e0cd99c1b0efb477b14"}, - {file = "meta_memcache_socket-0.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:39e7b14f54c634861a13befb5a753991f8535378237c0680f0445cbbf1a72509"}, - {file = "meta_memcache_socket-0.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1c25df35051ecdae27a6052d4d533f3e8290bf49ca7f51f6960691d990b9800"}, - {file = "meta_memcache_socket-0.1.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:815fd108ab5b3dfcf974315c88d799eff26801203d50d1cc31a1d387610626ce"}, - {file = "meta_memcache_socket-0.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f22f9dfcee14cfcc508d235e4862721a88d8167e75b51c1679876a807b2fa3cc"}, - {file = "meta_memcache_socket-0.1.0-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:89a197c4f9b62baf0ceede51e678d86a939083500f8d648315626f11d9fc19f4"}, - {file = "meta_memcache_socket-0.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e7e35b06f06292db5edcb542e14a3b875c215839e49dc3dd061dadcba6285d5"}, - {file = "meta_memcache_socket-0.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5741db35da60f514321430a24cafb8a45fd3c6253e19f193175446d1c71a66f8"}, - {file = "meta_memcache_socket-0.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3150319f6873ec8a65d523fc8da9fe2ee99154a2bc73552a8446510e556a500"}, - {file = "meta_memcache_socket-0.1.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bef08e5527df2e287e89bc04dda9fce554ddb7e782b497ab97b735ebca653792"}, - {file = "meta_memcache_socket-0.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0bd85fca14237950f850a7bfaaa9cdc09f7e63bc1f453eed58c5921cdfaaec46"}, - {file = "meta_memcache_socket-0.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f47eaa393d0cc5c4c2b4b87ee433698cda353e1d60107315891293bf7ef4eff0"}, - {file = "meta_memcache_socket-0.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:876767acbc5ae7ff7494bcbb2488b260928e0016bc73906bc94ce5be047fe974"}, - {file = "meta_memcache_socket-0.1.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bdbc18c52f844a0eea17037718931c44f79597d2a594c9cff58c0664e76df85b"}, - {file = "meta_memcache_socket-0.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50ba38faabaefe49b39c57e2abca30ffb060b6aaefb928fae9a940fa74a69856"}, - {file = "meta_memcache_socket-0.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d07f0f8e18f155c9d97a667a084d026aa16db681be020a7dad8d3443da073225"}, - {file = "meta_memcache_socket-0.1.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4652f1455e0478ee825ca6828b368f60f9acd582c2d94298e624cf2804bbaac3"}, - {file = "meta_memcache_socket-0.1.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:91b8aad8bfcb327f440cc6fbdc893aac20a36638b88fdd494ab1e36776455977"}, - {file = "meta_memcache_socket-0.1.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b0b338a9b0b07823d1653ab4a2f6d1d7db5e70416968e64cc070fd983d7e47c4"}, - {file = "meta_memcache_socket-0.1.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4de8135df114d97e99fa4171a10504812aaab2405e1ffb9987c4aa26ee11569b"}, - {file = "meta_memcache_socket-0.1.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f9baa601dba6cc9f6838472c9f8acbb4226a8279886e237c2f1a02ca752d558"}, - {file = "meta_memcache_socket-0.1.0-pp37-pypy37_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8fdf92bf7eec9b340c49f8059a3032cd5cf70dbf42eca1f5db65d5e51dc6ad17"}, - {file = "meta_memcache_socket-0.1.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4026106469d5fc707c5920b7ef98c5faad0fd8c9c2411c9cf169e629d433f7a5"}, - {file = "meta_memcache_socket-0.1.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5e56237cb45343135d4e78aaed1a6045d8f7a95beaba2a836a423c0dfa6a5799"}, - {file = "meta_memcache_socket-0.1.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d6e97e1ac7133bf3514c122aebd443754c7ac8138c27b48a4470e260b9092f4"}, - {file = "meta_memcache_socket-0.1.0-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e8766dbe2ebd9b9abe536eb62648e8edbff5c9e79bb60f7bd42bc8f09dca8825"}, - {file = "meta_memcache_socket-0.1.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d835e0b69c357ae83d17fd078efc0e464a62397ae732ca58e169381284311bfb"}, - {file = "meta_memcache_socket-0.1.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c10ccb6f62c90ab1bb6345ecf504e1d5d8450cd7a81be8d15322c1eff0c0e0e7"}, - {file = "meta_memcache_socket-0.1.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8164586cbc9ac16376945f14c261b49b8905f2d5b3ef2207cffe90a1f0ca86db"}, - {file = "meta_memcache_socket-0.1.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dd661f503ecc9ae8020bca79fcfb814f710df2e91cf98086636d5ae9e7689ef0"}, - {file = "meta_memcache_socket-0.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ab910371da3d13abd366d1fb36e0c961b5fbad85c257265bb18603dbd52d0d3"}, - {file = "meta_memcache_socket-0.1.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4b69fbb37d392d1cbae85deabc4efd475eea5867b6b45469add3300e21115880"}, - {file = "meta_memcache_socket-0.1.0.tar.gz", hash = "sha256:244a53055c069dd232dd8733c93a494ce4e437a5bfa2fb14ef7ec8f51c11d76d"}, + {file = "meta_memcache_socket-0.1.1-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:e58c0b96d58789bcd8018c3930436f8a1bdf0cec81e40c9872ab7fd09fc086ad"}, + {file = "meta_memcache_socket-0.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:101a29d94c2de5a9562c1ef0a1decda2a48b14a127a4aa560297cfab63b5076c"}, + {file = "meta_memcache_socket-0.1.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:641dbae8ae836a5cc2789e9b3554ee2a07ad4427cf2a401209c8086252dc9143"}, + {file = "meta_memcache_socket-0.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46e9bc46bab15bffc0e5ebc5cd2fc08beff3c4b6e58f3b0c152057a7440ac552"}, + {file = "meta_memcache_socket-0.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:de836ed9764197f02201cc77076fc3f41aaddfce266057c16f6b85cf8fe308a8"}, + {file = "meta_memcache_socket-0.1.1-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:2d484467397f9a506fa6a78dc5ff15d19f8292d774b04cab69d6be3e01966e1f"}, + {file = "meta_memcache_socket-0.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7ac0fc9ccc6e31e3af91ea727a5df19a61a6f07b3b4086902c31fa1cf0bb1cac"}, + {file = "meta_memcache_socket-0.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fda29ca3aa25330355808f5ad26c803c36cadbd162f24b953ca3256f920653e9"}, + {file = "meta_memcache_socket-0.1.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5c971a94d2213ffaaa1932116c881f8bb2c9c8d1f5d38f14769aa6493aaed980"}, + {file = "meta_memcache_socket-0.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5a682628d040e3c6500501a84b9d64a870fcdd781585fa2449c6c09e7f02f60"}, + {file = "meta_memcache_socket-0.1.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:26bc83b7ae9c359ae9a1e3a3670adf27a891b4b4d38aaa209e9d0116402448d5"}, + {file = "meta_memcache_socket-0.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2a8e1384f7e015ccf60e0d401545b8e694d4973f0d0a51d1b40d7fbd8de48024"}, + {file = "meta_memcache_socket-0.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:98084e3f37de9e1be657ca00cc8fabaa9d532c1316ea4db83d5633a8f01d70c9"}, + {file = "meta_memcache_socket-0.1.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8a0bf4dd2150c36cc80b4b5c356cf2adf1d6c599b005b9b09f9228f17f57fbfe"}, + {file = "meta_memcache_socket-0.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e1515cee9705b5411a2b50ec4f088561367d4d7d828c0effb8a9da8f8bc015f"}, + {file = "meta_memcache_socket-0.1.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d90b39eab5213ecbe21d298fde6b7a05d07bcf8707bcd389de94e62c54d36967"}, + {file = "meta_memcache_socket-0.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:432d24b52dbaa3feb537cb398e329620b0aef77cc59da3a9f5c712f7e8b4dddc"}, + {file = "meta_memcache_socket-0.1.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5cd55ed3fccf72a1a9fb6c0647d2c63d499776ba55c94f3116b818cbe16db102"}, + {file = "meta_memcache_socket-0.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d331be18a7f5b351326b46a5f9393cc7343bfe4fad158dbfbc2ef9c30ec4c66"}, + {file = "meta_memcache_socket-0.1.1-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:71667a4b26ff306e6cf59d0d1a792b5f3bfe2de2ee55cb187545329e4cb62252"}, + {file = "meta_memcache_socket-0.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:232cad68095402fdadfb8eaa1576e1ea2e1a5f21117242f14442081b98e871da"}, + {file = "meta_memcache_socket-0.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7bddfdee0abead430d573decaa1a52e1a417ac2e803c52d02d8f8bcf0c28523e"}, + {file = "meta_memcache_socket-0.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b424f67273ab0b7356e0b992a8e8d6ddd313c7d3cb3171777f7173af4fa61611"}, + {file = "meta_memcache_socket-0.1.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:305174c2f22cebcac557fdc708bca334eea994c539c18463cece381371fff50a"}, + {file = "meta_memcache_socket-0.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:406b3bcc854ea825a54c6cd04449263e5700fbd07c8f8b515b753305e185c1ee"}, + {file = "meta_memcache_socket-0.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c3985e25d04bc3bf3cb0602512dca21372a51a7e7975ecca266f1252a09ac1f8"}, + {file = "meta_memcache_socket-0.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:358abe4222f1ef10e907bfefd3aba71a2a2337af43817144a2eb25501b4184d8"}, + {file = "meta_memcache_socket-0.1.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2803528ad935f769367001210ddff68420d4da23800422ccea7d343fd2c45e52"}, + {file = "meta_memcache_socket-0.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c6f93c03d3239af3bab766ccdb297f216ffaab6061596d09eb9f9ee2b30ed7b"}, + {file = "meta_memcache_socket-0.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d929b77fe8edf8685ed55345d425f0db80256b13f2b4132386e3def246484b18"}, + {file = "meta_memcache_socket-0.1.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9e741669984d69ac48c78bb5595e36f5205d3bdaa5f259547f5a651a71debb5"}, + {file = "meta_memcache_socket-0.1.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8c31615685db11603e5e32d07163029660100d0ae1c96b963f78b8a6336eba90"}, + {file = "meta_memcache_socket-0.1.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:690761adc29ad7a516374544483b46059e5bf83afb11e5aa49723fd971a077a4"}, + {file = "meta_memcache_socket-0.1.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fde68dde315f98190aae95448cdb60a1862b12b01b9e944530add32368a64efa"}, + {file = "meta_memcache_socket-0.1.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:060abd5a8f8a721623cc2a26d7e99174b79c9ff538dde8d015e26513ae7f1a13"}, + {file = "meta_memcache_socket-0.1.1-pp37-pypy37_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff43c1344d0fbff82a808866378d02c7261fa1e63c5b4a3606d02cefb0802f04"}, + {file = "meta_memcache_socket-0.1.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf21246a4acc9e3157cddef646e4920d6e40645fc9143de5c3b82de251a7c5d3"}, + {file = "meta_memcache_socket-0.1.1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:74c96deefc79c59262f1c63e6431e8d733f6ee646239f72be593784916e1faa2"}, + {file = "meta_memcache_socket-0.1.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab8b8f9b51a86bb36bb8c4c60dab19bbcb43ddc26ae8c22502d4c3b6a17955a8"}, + {file = "meta_memcache_socket-0.1.1-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:96dea2e9ad7a0c7d36d912be5c8ceb26de4a6c0d126666d6f52a586ddc34b279"}, + {file = "meta_memcache_socket-0.1.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd1cf2de55ef6c4bcdce2f09bee06cf4d2f5a4c76ea126b5f9e876dba158637f"}, + {file = "meta_memcache_socket-0.1.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5bf457e3bd82c6bd7f186f549a27e924e0cec02fb3ab54c1a840a6cf5e80db3a"}, + {file = "meta_memcache_socket-0.1.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ac9bf7728be05b4e010dab3ab2c426aa26bab5d76176cf70b292fc40ad2e14b"}, + {file = "meta_memcache_socket-0.1.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e34f7f8f3f520e2ec2270ad04d53fa75bad3a0b7e4331f5f8cd6c35cff3de7a5"}, + {file = "meta_memcache_socket-0.1.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a74654809003ef52171c9da320a60d9128c59a917a626d726b09a1411e15b933"}, + {file = "meta_memcache_socket-0.1.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:912ee61b16973a8b48e3bbfab9af99121e1ec4dfbcc77633f67cb705574abca5"}, + {file = "meta_memcache_socket-0.1.1.tar.gz", hash = "sha256:d7e450e88c168b694ae540202522c7b12e56b3a6e26969d59be43da6739e2743"}, ] [[package]] @@ -177,4 +175,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "ce30e2f682597672f0fc2ef59821c0be70841bfd087134b66b86c1f7580d7d25" +content-hash = "28444a6c5cbc6d48a1bcb8cc13e85b6ea1a2bd1d5880b31cf16d7737ab8f491d" diff --git a/pyproject.toml b/pyproject.toml index 8646d48..e8cc412 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ packages = [{include = "meta_memcache", from="src"}] python = "^3.8" uhashring = "^2.1" marisa-trie = "^1.0.0" -meta-memcache-socket = "^0.1.0" +meta-memcache-socket = "0.1.1" [tool.poetry.group.extras.dependencies] prometheus-client = "^0.17.1" diff --git a/src/meta_memcache/__init__.py b/src/meta_memcache/__init__.py index 6dee464..fc6472b 100644 --- a/src/meta_memcache/__init__.py +++ b/src/meta_memcache/__init__.py @@ -33,17 +33,15 @@ ) from meta_memcache.protocol import ( Conflict, - Flag, - IntFlag, Key, MetaCommand, Miss, NotStored, ServerVersion, ResponseFlags, + RequestFlags, SetMode, Success, - TokenFlag, Value, ) from meta_memcache.routers.default import DefaultRouter diff --git a/src/meta_memcache/cache_client.py b/src/meta_memcache/cache_client.py index b09f8ae..f6601f0 100644 --- a/src/meta_memcache/cache_client.py +++ b/src/meta_memcache/cache_client.py @@ -1,4 +1,4 @@ -from typing import Callable, Iterable, Optional, Tuple +from typing import Callable, Iterable, Optional from meta_memcache.base.base_cache_client import BaseCacheClient from meta_memcache.commands.high_level_commands import HighLevelCommandsMixin @@ -25,7 +25,7 @@ def cache_client_from_servers( servers: Iterable[ServerAddress], connection_pool_factory_fn: Callable[[ServerAddress], ConnectionPool], serializer: Optional[BaseSerializer] = None, - key_encoder_fn: Callable[[Key], Tuple[bytes, bool]] = default_key_encoder, + key_encoder_fn: Callable[[Key], bytes] = default_key_encoder, raise_on_server_error: bool = True, ) -> CacheApi: executor = DefaultExecutor( @@ -48,7 +48,7 @@ def cache_client_with_gutter_from_servers( gutter_ttl: int, connection_pool_factory_fn: Callable[[ServerAddress], ConnectionPool], serializer: Optional[BaseSerializer] = None, - key_encoder_fn: Callable[[Key], Tuple[bytes, bool]] = default_key_encoder, + key_encoder_fn: Callable[[Key], bytes] = default_key_encoder, raise_on_server_error: bool = True, ) -> CacheApi: executor = DefaultExecutor( @@ -76,7 +76,7 @@ def ephemeral_cache_client_from_servers( max_ttl: int, connection_pool_factory_fn: Callable[[ServerAddress], ConnectionPool], serializer: Optional[BaseSerializer] = None, - key_encoder_fn: Callable[[Key], Tuple[bytes, bool]] = default_key_encoder, + key_encoder_fn: Callable[[Key], bytes] = default_key_encoder, raise_on_server_error: bool = True, ) -> CacheApi: executor = DefaultExecutor( diff --git a/src/meta_memcache/commands/high_level_commands.py b/src/meta_memcache/commands/high_level_commands.py index 356bf1d..57dbc10 100644 --- a/src/meta_memcache/commands/high_level_commands.py +++ b/src/meta_memcache/commands/high_level_commands.py @@ -5,7 +5,6 @@ Iterable, Optional, Protocol, - Set, Tuple, Type, TypeVar, @@ -18,35 +17,33 @@ from meta_memcache.interfaces.meta_commands import MetaCommandsProtocol from meta_memcache.interfaces.router import FailureHandling from meta_memcache.protocol import ( - Flag, - IntFlag, Key, Miss, ReadResponse, + RequestFlags, SetMode, Success, - TokenFlag, Value, + MA_MODE_DEC, ) T = TypeVar("T") _REFILL_FAILURE_HANDLING = FailureHandling(track_write_failures=False) - -DEFAULT_FLAGS: Set[Flag] = { - Flag.RETURN_VALUE, - Flag.RETURN_TTL, - Flag.RETURN_CLIENT_FLAG, - Flag.RETURN_LAST_ACCESS, - Flag.RETURN_FETCHED, -} -DEFAULT_CAS_FLAGS: Set[Flag] = { - Flag.RETURN_VALUE, - Flag.RETURN_TTL, - Flag.RETURN_CLIENT_FLAG, - Flag.RETURN_LAST_ACCESS, - Flag.RETURN_FETCHED, - Flag.RETURN_CAS_TOKEN, -} +DEFAULT_GET_FLAGS = RequestFlags( + return_value=True, + return_ttl=True, + return_client_flag=True, + return_last_access=True, + return_fetched=True, +) +DEFAULT_GET_CAS_FLAGS = RequestFlags( + return_value=True, + return_ttl=True, + return_client_flag=True, + return_last_access=True, + return_fetched=True, + return_cas_token=True, +) class HighLevelCommandMixinWithMetaCommands( @@ -80,9 +77,7 @@ def _get_delta_flags( no_reply: bool = False, cas_token: Optional[int] = None, return_value: bool = False, - ) -> Tuple[ - Set[Flag], Dict[IntFlag, int], Dict[TokenFlag, bytes] - ]: ... # pragma: no cover + ) -> RequestFlags: ... # pragma: no cover class HighLevelCommandsMixin: @@ -97,28 +92,21 @@ def set( set_mode: SetMode = SetMode.SET, ) -> bool: key = key if isinstance(key, Key) else Key(key) - flags: Set[Flag] = set() + flags = RequestFlags(cache_ttl=ttl) if no_reply: - flags.add(Flag.NOREPLY) - int_flags: Dict[IntFlag, int] = { - IntFlag.CACHE_TTL: ttl, - } + flags.no_reply = True if cas_token is not None: - int_flags[IntFlag.CAS_TOKEN] = cas_token + flags.cas_token = cas_token if stale_policy and stale_policy.mark_stale_on_cas_mismatch: - flags.add(Flag.MARK_STALE) - if set_mode == SetMode.SET: - token_flags = None - else: - token_flags = {TokenFlag.MODE: set_mode.value} + flags.mark_stale = True + if set_mode != SetMode.SET: + flags.mode = set_mode.value result = self.meta_set( key=key, value=value, ttl=ttl, flags=flags, - int_flags=int_flags, - token_flags=token_flags, ) return isinstance(result, Success) @@ -147,17 +135,18 @@ def refill( there is no need to track failures. """ key = key if isinstance(key, Key) else Key(key) - flags: Set[Flag] = set() + flags = RequestFlags( + cache_ttl=ttl, + mode=SetMode.ADD.value, + ) if no_reply: - flags.add(Flag.NOREPLY) + flags.no_reply = True result = self.meta_set( key=key, value=value, ttl=ttl, flags=flags, - int_flags={IntFlag.CACHE_TTL: ttl}, - token_flags={TokenFlag.MODE: SetMode.ADD.value}, failure_handling=_REFILL_FAILURE_HANDLING, ) @@ -177,21 +166,16 @@ def delete( it exists or not, use invalidate() instead. """ key = key if isinstance(key, Key) else Key(key) - flags: Set[Flag] = set() - int_flags: Dict[IntFlag, int] = {} + flags = RequestFlags() if no_reply: - flags.add(Flag.NOREPLY) + flags.no_reply = True if cas_token is not None: - int_flags[IntFlag.CAS_TOKEN] = cas_token + flags.cas_token = cas_token if stale_policy and stale_policy.mark_stale_on_deletion_ttl > 0: - flags.add(Flag.MARK_STALE) - int_flags[IntFlag.CACHE_TTL] = stale_policy.mark_stale_on_deletion_ttl + flags.mark_stale = True + flags.cache_ttl = stale_policy.mark_stale_on_deletion_ttl - result = self.meta_delete( - key=key, - flags=flags, - int_flags=int_flags, - ) + result = self.meta_delete(key=key, flags=flags) return isinstance(result, Success) @@ -206,21 +190,16 @@ def invalidate( Returns true of the key deleted or it didn't exist anyway """ key = key if isinstance(key, Key) else Key(key) - flags: Set[Flag] = set() - int_flags: Dict[IntFlag, int] = {} + flags = RequestFlags() if no_reply: - flags.add(Flag.NOREPLY) + flags.no_reply = True if cas_token is not None: - int_flags[IntFlag.CAS_TOKEN] = cas_token + flags.cas_token = cas_token if stale_policy and stale_policy.mark_stale_on_deletion_ttl > 0: - flags.add(Flag.MARK_STALE) - int_flags[IntFlag.CACHE_TTL] = stale_policy.mark_stale_on_deletion_ttl + flags.mark_stale = True + flags.cache_ttl = stale_policy.mark_stale_on_deletion_ttl - result = self.meta_delete( - key=key, - flags=flags, - int_flags=int_flags, - ) + result = self.meta_delete(key=key, flags=flags) return isinstance(result, (Success, Miss)) @@ -231,11 +210,10 @@ def touch( no_reply: bool = False, ) -> bool: key = key if isinstance(key, Key) else Key(key) - flags: Set[Flag] = set() - int_flags = {IntFlag.CACHE_TTL: ttl} + flags = RequestFlags(cache_ttl=ttl) if no_reply: - flags.add(Flag.NOREPLY) - result = self.meta_get(key, flags=flags, int_flags=int_flags) + flags.no_reply = True + result = self.meta_get(key, flags=flags) return isinstance(result, Success) @@ -344,22 +322,17 @@ def _multi_get( return_cas_token: bool = False, ) -> Dict[Key, Optional[Value]]: if return_cas_token: - flags = DEFAULT_CAS_FLAGS.copy() - else: - flags = DEFAULT_FLAGS.copy() - if recache_policy is None and touch_ttl is None: - int_flags = None + flags = DEFAULT_GET_CAS_FLAGS.copy() else: - int_flags = {} - if recache_policy: - int_flags[IntFlag.RECACHE_TTL] = recache_policy.ttl - if touch_ttl is not None and touch_ttl >= 0: - int_flags[IntFlag.CACHE_TTL] = touch_ttl + flags = DEFAULT_GET_FLAGS.copy() + if recache_policy: + flags.recache_ttl = recache_policy.ttl + if touch_ttl is not None and touch_ttl >= 0: + flags.cache_ttl = touch_ttl results = self.meta_multiget( keys=[key if isinstance(key, Key) else Key(key) for key in keys], flags=flags, - int_flags=int_flags, ) return {k: self._process_get_result(k, v) for k, v in results.items()} @@ -390,21 +363,17 @@ def _get( ) -> Optional[Value]: key = key if isinstance(key, Key) else Key(key) if return_cas_token: - flags = DEFAULT_CAS_FLAGS.copy() - else: - flags = DEFAULT_FLAGS.copy() - if lease_policy is None and recache_policy is None and touch_ttl is None: - int_flags = None + flags = DEFAULT_GET_CAS_FLAGS.copy() else: - int_flags = {} - if lease_policy: - int_flags[IntFlag.MISS_LEASE_TTL] = lease_policy.ttl - if recache_policy: - int_flags[IntFlag.RECACHE_TTL] = recache_policy.ttl - if touch_ttl is not None and touch_ttl >= 0: - int_flags[IntFlag.CACHE_TTL] = touch_ttl - - result = self.meta_get(key, flags=flags, int_flags=int_flags) + flags = DEFAULT_GET_FLAGS.copy() + if lease_policy: + flags.vivify_on_miss_ttl = lease_policy.ttl + if recache_policy: + flags.recache_ttl = recache_policy.ttl + if touch_ttl is not None and touch_ttl >= 0: + flags.cache_ttl = touch_ttl + + result = self.meta_get(key, flags=flags) return self._process_get_result(key, result) def _process_get_result( @@ -475,25 +444,22 @@ def _get_delta_flags( no_reply: bool = False, cas_token: Optional[int] = None, return_value: bool = False, - ) -> Tuple[Set[Flag], Dict[IntFlag, int], Dict[TokenFlag, bytes]]: - flags: Set[Flag] = set() - int_flags: Dict[IntFlag, int] = { - IntFlag.MA_DELTA_VALUE: abs(delta), - } - token_flags: Dict[TokenFlag, bytes] = {} - + ) -> RequestFlags: + flags = RequestFlags( + ma_delta_value=abs(delta), + ) if return_value: - flags.add(Flag.RETURN_VALUE) + flags.return_value = True if no_reply: - flags.add(Flag.NOREPLY) + flags.no_reply = True if refresh_ttl is not None: - int_flags[IntFlag.CACHE_TTL] = refresh_ttl + flags.cache_ttl = refresh_ttl if cas_token is not None: - int_flags[IntFlag.CAS_TOKEN] = cas_token + flags.cas_token = cas_token if delta < 0: - token_flags[TokenFlag.MODE] = b"-" + flags.mode = MA_MODE_DEC - return flags, int_flags, token_flags + return flags def delta( self: HighLevelCommandMixinWithMetaCommands, @@ -504,15 +470,13 @@ def delta( cas_token: Optional[int] = None, ) -> bool: key = key if isinstance(key, Key) else Key(key) - flags, int_flags, token_flags = self._get_delta_flags( + flags = self._get_delta_flags( delta=delta, refresh_ttl=refresh_ttl, no_reply=no_reply, cas_token=cas_token, ) - result = self.meta_arithmetic( - key=key, flags=flags, int_flags=int_flags, token_flags=token_flags - ) + result = self.meta_arithmetic(key=key, flags=flags) return isinstance(result, Success) def delta_initialize( @@ -526,17 +490,15 @@ def delta_initialize( cas_token: Optional[int] = None, ) -> bool: key = key if isinstance(key, Key) else Key(key) - flags, int_flags, token_flags = self._get_delta_flags( + flags = self._get_delta_flags( delta=delta, refresh_ttl=refresh_ttl, no_reply=no_reply, cas_token=cas_token, ) - int_flags[IntFlag.MA_INITIAL_VALUE] = abs(initial_value) - int_flags[IntFlag.MISS_LEASE_TTL] = initial_ttl - result = self.meta_arithmetic( - key=key, flags=flags, int_flags=int_flags, token_flags=token_flags - ) + flags.ma_initial_value = abs(initial_value) + flags.vivify_on_miss_ttl = initial_ttl + result = self.meta_arithmetic(key=key, flags=flags) return isinstance(result, Success) def delta_and_get( @@ -547,15 +509,13 @@ def delta_and_get( cas_token: Optional[int] = None, ) -> Optional[int]: key = key if isinstance(key, Key) else Key(key) - flags, int_flags, token_flags = self._get_delta_flags( + flags = self._get_delta_flags( return_value=True, delta=delta, refresh_ttl=refresh_ttl, cas_token=cas_token, ) - result = self.meta_arithmetic( - key=key, flags=flags, int_flags=int_flags, token_flags=token_flags - ) + result = self.meta_arithmetic(key=key, flags=flags) if isinstance(result, Value): if isinstance(result.value, str) and result.value.isnumeric(): return int(result.value) @@ -575,17 +535,15 @@ def delta_initialize_and_get( cas_token: Optional[int] = None, ) -> Optional[int]: key = key if isinstance(key, Key) else Key(key) - flags, int_flags, token_flags = self._get_delta_flags( + flags = self._get_delta_flags( return_value=True, delta=delta, refresh_ttl=refresh_ttl, cas_token=cas_token, ) - int_flags[IntFlag.MA_INITIAL_VALUE] = abs(initial_value) - int_flags[IntFlag.MISS_LEASE_TTL] = initial_ttl - result = self.meta_arithmetic( - key=key, flags=flags, int_flags=int_flags, token_flags=token_flags - ) + flags.ma_initial_value = abs(initial_value) + flags.vivify_on_miss_ttl = initial_ttl + result = self.meta_arithmetic(key=key, flags=flags) if isinstance(result, Value): if isinstance(result.value, str) and result.value.isnumeric(): return int(result.value) diff --git a/src/meta_memcache/commands/meta_commands.py b/src/meta_memcache/commands/meta_commands.py index 6d1901e..647f95e 100644 --- a/src/meta_memcache/commands/meta_commands.py +++ b/src/meta_memcache/commands/meta_commands.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, List, Optional, Set +from typing import Any, Dict, List, Optional from meta_memcache.errors import MemcacheError from meta_memcache.interfaces.router import ( @@ -8,15 +8,13 @@ ) from meta_memcache.protocol import ( Conflict, - Flag, - IntFlag, Key, MetaCommand, Miss, NotStored, ReadResponse, + RequestFlags, Success, - TokenFlag, Value, ValueContainer, WriteResponse, @@ -27,9 +25,7 @@ class MetaCommandsMixin: def meta_multiget( self: HasRouter, keys: List[Key], - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> Dict[Key, ReadResponse]: results: Dict[Key, ReadResponse] = {} @@ -37,8 +33,6 @@ def meta_multiget( command=MetaCommand.META_GET, keys=keys, flags=flags, - int_flags=int_flags, - token_flags=token_flags, failure_handling=failure_handling, ).items(): if not isinstance(result, (Miss, Value, Success)): @@ -51,17 +45,13 @@ def meta_multiget( def meta_get( self: HasRouter, key: Key, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> ReadResponse: result = self.router.exec( command=MetaCommand.META_GET, key=key, flags=flags, - int_flags=int_flags, - token_flags=token_flags, failure_handling=failure_handling, ) if not isinstance(result, (Miss, Value, Success)): @@ -73,9 +63,7 @@ def meta_set( key: Key, value: Any, ttl: int, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> WriteResponse: result = self.router.exec( @@ -83,8 +71,6 @@ def meta_set( key=key, value=ValueContainer(value), flags=flags, - int_flags=int_flags, - token_flags=token_flags, failure_handling=failure_handling, ) if not isinstance(result, (Success, NotStored, Conflict, Miss)): @@ -94,17 +80,13 @@ def meta_set( def meta_delete( self: HasRouter, key: Key, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> WriteResponse: result = self.router.exec( command=MetaCommand.META_DELETE, key=key, flags=flags, - int_flags=int_flags, - token_flags=token_flags, failure_handling=failure_handling, ) if not isinstance(result, (Success, NotStored, Conflict, Miss)): @@ -116,17 +98,13 @@ def meta_delete( def meta_arithmetic( self: HasRouter, key: Key, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> WriteResponse: result = self.router.exec( command=MetaCommand.META_ARITHMETIC, key=key, flags=flags, - int_flags=int_flags, - token_flags=token_flags, failure_handling=failure_handling, ) if not isinstance(result, (Success, NotStored, Conflict, Miss, Value)): diff --git a/src/meta_memcache/configuration.py b/src/meta_memcache/configuration.py index bc92ffa..ab2911e 100644 --- a/src/meta_memcache/configuration.py +++ b/src/meta_memcache/configuration.py @@ -1,8 +1,7 @@ -import base64 import hashlib import socket from enum import IntEnum -from typing import Callable, Dict, Iterable, NamedTuple, Optional, Tuple +from typing import Callable, Dict, Iterable, NamedTuple, Optional from meta_memcache.connection.pool import ConnectionPool from meta_memcache.protocol import Key, ServerVersion @@ -157,17 +156,18 @@ class StalePolicy(NamedTuple): mark_stale_on_cas_mismatch: bool = False -def default_key_encoder(key: Key) -> Tuple[bytes, bool]: +def default_key_encoder(key: Key) -> bytes: """ Generate valid memcache key as bytes for given Key. """ - if key.is_unicode or len(key.key) > MAX_KEY_SIZE: - key_hash = hashlib.blake2b(key.key.encode(), digest_size=18).digest() - return base64.b64encode(key_hash), True - elif " " in key.key: - raise ValueError(f"Invalid key {key}") - else: - return key.key.encode("ascii"), False + # TODO: Support + # if isinstance(key.key, bytes): + # data = key.key + # else: + data = key.key.encode() + if len(data) >= MAX_KEY_SIZE: + data = hashlib.blake2b(data, digest_size=18).digest() + return data class MigrationMode(IntEnum): diff --git a/src/meta_memcache/connection/memcache_socket.py b/src/meta_memcache/connection/memcache_socket.py index 5240347..ca8e41f 100644 --- a/src/meta_memcache/connection/memcache_socket.py +++ b/src/meta_memcache/connection/memcache_socket.py @@ -8,7 +8,6 @@ from meta_memcache.protocol import ( ENDL, ENDL_LEN, - EMPTY_RESPONSE_FLAGS, NOOP, Conflict, Miss, @@ -135,13 +134,12 @@ def _get_single_header( while True: if self._read != self._pos: - # We have data in the buffer: find the header + # We have data in the buffer: Try to find the header if header_data := meta_memcache_socket.parse_header( self._buf_view, self._pos, self._read ): self._pos = header_data[0] return header_data - # Missing data, but still space in buffer, so read more if self._recv_info_buffer() <= 0: break @@ -178,15 +176,13 @@ def get_response( result: Union[Value, Success, NotStored, Conflict, Miss] try: if response_code == meta_memcache_socket.RESPONSE_VALUE: - if size is None: - raise MemcacheError("Bad value response. Missing size") # Value response - result = Value( - size=size, flags=flags or EMPTY_RESPONSE_FLAGS, value=None - ) + assert size is not None and flags is not None # noqa: S101 + result = Value(size=size, flags=flags, value=None) elif response_code == meta_memcache_socket.RESPONSE_SUCCESS: # Stored or no value, return Success - result = Success(flags=flags or EMPTY_RESPONSE_FLAGS) + assert flags is not None # noqa: S101 + result = Success(flags=flags) elif response_code == meta_memcache_socket.RESPONSE_NOT_STORED: # Value response, parse size and flags result = NOT_STORED diff --git a/src/meta_memcache/executors/default.py b/src/meta_memcache/executors/default.py index 0383aa6..7be50a2 100644 --- a/src/meta_memcache/executors/default.py +++ b/src/meta_memcache/executors/default.py @@ -1,5 +1,13 @@ import logging -from typing import Callable, Dict, List, Optional, Set, Tuple +from typing import Callable, Dict, List, Optional, Tuple + +from meta_memcache_socket import ( + RequestFlags, + build_meta_get, + build_meta_delete, + build_meta_set, + build_meta_arithmetic, +) from meta_memcache.base.base_serializer import BaseSerializer from meta_memcache.configuration import default_key_encoder @@ -9,8 +17,6 @@ from meta_memcache.events.write_failure_event import WriteFailureEvent from meta_memcache.protocol import ( ENDL, - Flag, - IntFlag, Key, MaybeValue, MemcacheResponse, @@ -20,10 +26,8 @@ ResponseFlags, ServerVersion, Success, - TokenFlag, Value, ValueContainer, - encode_size, ) _log: logging.Logger = logging.getLogger(__name__) @@ -33,7 +37,7 @@ class DefaultExecutor: def __init__( self, serializer: BaseSerializer, - key_encoder_fn: Callable[[Key], Tuple[bytes, bool]] = default_key_encoder, + key_encoder_fn: Callable[[Key], bytes] = default_key_encoder, raise_on_server_error: bool = True, touch_ttl_to_consider_write_failure: Optional[int] = 50, ) -> None: @@ -48,41 +52,32 @@ def _build_cmd( command: MetaCommand, key: Key, size: Optional[int] = None, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, version: ServerVersion = ServerVersion.STABLE, ) -> bytes: - encoded_key, is_binary = self._key_encoder_fn(key) - cmd = [command.value, encoded_key] - if size is not None: - cmd.append(encode_size(size, version=version)) - cmd_flags: List[bytes] = [] - if is_binary: - cmd_flags.append(Flag.BINARY.value) - if flags: - cmd_flags.extend(flag.value for flag in flags) - if int_flags: - for int_flag, int_value in int_flags.items(): - cmd_flags.append(int_flag.value + str(int_value).encode("ascii")) - if token_flags: - for token_flag, bytes_value in token_flags.items(): - cmd_flags.append(token_flag.value + bytes_value) - cmd.extend(cmd_flags) - return b" ".join(cmd) + ENDL + encoded_key = self._key_encoder_fn(key) + if command == MetaCommand.META_GET: + return build_meta_get(encoded_key, flags) + elif command == MetaCommand.META_SET: + legazy_size_format = version == ServerVersion.AWS_1_6_6 + return build_meta_set(encoded_key, size, flags, legazy_size_format) + elif command == MetaCommand.META_DELETE: + return build_meta_delete(encoded_key, flags) + elif command == MetaCommand.META_ARITHMETIC: + return build_meta_arithmetic(encoded_key, flags) - def _prepare_serialized_value_and_int_flags( + def _prepare_serialized_value_and_flags( self, value: ValueContainer, - int_flags: Optional[Dict[IntFlag, int]], - ) -> Tuple[Optional[bytes], Optional[Dict[IntFlag, int]]]: + flags: Optional[RequestFlags], + ) -> Tuple[Optional[bytes], RequestFlags]: encoded_value = self._serializer.serialize(value.value) - int_flags = int_flags if int_flags is not None else {} - int_flags[IntFlag.SET_CLIENT_FLAG] = encoded_value.encoding_id - return encoded_value.data, int_flags + flags = flags if flags is not None else RequestFlags() + flags.client_flag = encoded_value.encoding_id + return encoded_value.data, flags def _is_a_write_failure( - self, command: MetaCommand, int_flags: Optional[Dict[IntFlag, int]] + self, command: MetaCommand, flags: Optional[RequestFlags] ) -> bool: if command in ( MetaCommand.META_DELETE, @@ -92,7 +87,7 @@ def _is_a_write_failure( if ( self._touch_ttl_to_consider_write_failure is not None and command == MetaCommand.META_GET - and (touch_ttl := (int_flags or {}).get(IntFlag.CACHE_TTL, None)) + and (touch_ttl := (flags.cache_ttl if flags else None)) and 0 < touch_ttl <= self._touch_ttl_to_consider_write_failure ): return True @@ -104,16 +99,14 @@ def exec_on_pool( command: MetaCommand, key: Key, value: MaybeValue, - flags: Optional[Set[Flag]], - int_flags: Optional[Dict[IntFlag, int]], - token_flags: Optional[Dict[TokenFlag, bytes]], + flags: Optional[RequestFlags], track_write_failures: bool, raise_on_server_error: Optional[bool] = None, ) -> MemcacheResponse: - cmd_value, int_flags = ( - (None, int_flags) + cmd_value, flags = ( + (None, flags) if value is None - else self._prepare_serialized_value_and_int_flags(value, int_flags) + else self._prepare_serialized_value_and_flags(value, flags) ) try: conn = pool.pop_connection() @@ -125,8 +118,6 @@ def exec_on_pool( key=key, value=cmd_value, flags=flags, - int_flags=int_flags, - token_flags=token_flags, ) return self._conn_recv_response(conn, flags=flags) except Exception as e: @@ -135,7 +126,7 @@ def exec_on_pool( finally: pool.release_connection(conn, error=error) except MemcacheServerError: - if track_write_failures and self._is_a_write_failure(command, int_flags): + if track_write_failures and self._is_a_write_failure(command, flags): self.on_write_failure(key) raise_on_server_error = ( raise_on_server_error @@ -154,9 +145,7 @@ def exec_multi_on_pool( # noqa: C901 pool: ConnectionPool, command: MetaCommand, key_values: List[Tuple[Key, MaybeValue]], - flags: Optional[Set[Flag]], - int_flags: Optional[Dict[IntFlag, int]], - token_flags: Optional[Dict[TokenFlag, bytes]], + flags: Optional[RequestFlags], track_write_failures: bool, raise_on_server_error: Optional[bool] = None, ) -> Dict[Key, MemcacheResponse]: @@ -167,12 +156,10 @@ def exec_multi_on_pool( # noqa: C901 try: # with pool.get_connection() as conn: for key, value in key_values: - cmd_value, int_flags = ( - (None, int_flags) + cmd_value, flags = ( + (None, flags) if value is None - else self._prepare_serialized_value_and_int_flags( - value, int_flags - ) + else self._prepare_serialized_value_and_flags(value, flags) ) self._conn_send_cmd( @@ -181,8 +168,6 @@ def exec_multi_on_pool( # noqa: C901 key=key, value=cmd_value, flags=flags, - int_flags=int_flags, - token_flags=token_flags, ) for key, _ in key_values: results[key] = self._conn_recv_response(conn, flags=flags) @@ -192,7 +177,7 @@ def exec_multi_on_pool( # noqa: C901 finally: pool.release_connection(conn, error=error) except MemcacheServerError: - if track_write_failures and self._is_a_write_failure(command, int_flags): + if track_write_failures and self._is_a_write_failure(command, flags): for key, _ in key_values: self.on_write_failure(key) raise_on_server_error = ( @@ -215,9 +200,7 @@ def _conn_send_cmd( command: MetaCommand, key: Key, value: Optional[bytes] = None, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, ) -> None: """ Execute command on a connection @@ -227,16 +210,12 @@ def _conn_send_cmd( key, size=len(value) if value is not None else None, flags=flags, - int_flags=int_flags, - token_flags=token_flags, version=conn.get_version(), ) # write meta commands with NOREPLY can potentially return errors # they are not fully silent, so we need to add a no-op to the wire. with_noop = ( - command != MetaCommand.META_GET - and flags is not None - and Flag.NOREPLY in flags + command != MetaCommand.META_GET and flags is not None and flags.no_reply ) if value: @@ -247,12 +226,12 @@ def _conn_send_cmd( def _conn_recv_response( self, conn: MemcacheSocket, - flags: Optional[Set[Flag]] = None, + flags: Optional[RequestFlags] = None, ) -> MemcacheResponse: """ Read response on a connection """ - if flags and Flag.NOREPLY in flags: + if flags and flags.no_reply: return Success(flags=ResponseFlags()) result = conn.get_response() if isinstance(result, Value): diff --git a/src/meta_memcache/extras/client_wrapper.py b/src/meta_memcache/extras/client_wrapper.py index 61f6678..6a1f6be 100644 --- a/src/meta_memcache/extras/client_wrapper.py +++ b/src/meta_memcache/extras/client_wrapper.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, List, Optional, Set +from typing import Any, Dict, List, Optional from meta_memcache.commands.high_level_commands import HighLevelCommandsMixin from meta_memcache.configuration import ServerAddress @@ -6,11 +6,9 @@ from meta_memcache.interfaces.router import FailureHandling, DEFAULT_FAILURE_HANDLING from meta_memcache.interfaces.cache_api import CacheApi from meta_memcache.protocol import ( - Flag, - IntFlag, Key, ReadResponse, - TokenFlag, + RequestFlags, WriteResponse, ) @@ -33,32 +31,24 @@ def __init__( def meta_multiget( self, keys: List[Key], - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> Dict[Key, ReadResponse]: return self.client.meta_multiget( keys=keys, flags=flags, - int_flags=int_flags, - token_flags=token_flags, failure_handling=failure_handling, ) def meta_get( self, key: Key, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> ReadResponse: return self.client.meta_get( key=key, flags=flags, - int_flags=int_flags, - token_flags=token_flags, failure_handling=failure_handling, ) @@ -67,9 +57,7 @@ def meta_set( key: Key, value: Any, ttl: int, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> WriteResponse: return self.client.meta_set( @@ -77,40 +65,30 @@ def meta_set( value=value, ttl=ttl, flags=flags, - int_flags=int_flags, - token_flags=token_flags, failure_handling=failure_handling, ) def meta_delete( self, key: Key, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> WriteResponse: return self.client.meta_delete( key=key, flags=flags, - int_flags=int_flags, - token_flags=token_flags, failure_handling=failure_handling, ) def meta_arithmetic( self, key: Key, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> WriteResponse: return self.client.meta_arithmetic( key=key, flags=flags, - int_flags=int_flags, - token_flags=token_flags, failure_handling=failure_handling, ) diff --git a/src/meta_memcache/extras/migrating_cache_client.py b/src/meta_memcache/extras/migrating_cache_client.py index 664ffd4..31bde8c 100644 --- a/src/meta_memcache/extras/migrating_cache_client.py +++ b/src/meta_memcache/extras/migrating_cache_client.py @@ -1,6 +1,6 @@ import random import time -from typing import Any, Dict, List, Optional, Set, Union +from typing import Any, Dict, List, Optional, Union from meta_memcache.commands.high_level_commands import HighLevelCommandsMixin from meta_memcache.configuration import MigrationMode, ServerAddress @@ -8,11 +8,9 @@ from meta_memcache.events.write_failure_event import WriteFailureEvent from meta_memcache.interfaces.cache_api import CacheApi from meta_memcache.protocol import ( - Flag, - IntFlag, Key, ReadResponse, - TokenFlag, + RequestFlags, Value, WriteResponse, ) @@ -97,9 +95,7 @@ def _should_populate_read(self, migration_mode: MigrationMode) -> bool: def meta_multiget( self, keys: List[Key], - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> Dict[Key, ReadResponse]: migration_mode = self.get_migration_mode() @@ -107,8 +103,6 @@ def meta_multiget( return self._destination_client.meta_multiget( keys=keys, flags=flags, - int_flags=int_flags, - token_flags=token_flags, failure_handling=failure_handling, ) elif migration_mode in ( @@ -118,8 +112,6 @@ def meta_multiget( results = self._origin_client.meta_multiget( keys=keys, flags=flags, - int_flags=int_flags, - token_flags=token_flags, failure_handling=failure_handling, ) if self._should_populate_read(migration_mode): @@ -136,17 +128,13 @@ def meta_multiget( return self._origin_client.meta_multiget( keys=keys, flags=flags, - int_flags=int_flags, - token_flags=token_flags, failure_handling=failure_handling, ) def meta_get( self, key: Key, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> ReadResponse: migration_mode = self.get_migration_mode() @@ -154,8 +142,6 @@ def meta_get( return self._destination_client.meta_get( key=key, flags=flags, - int_flags=int_flags, - token_flags=token_flags, failure_handling=failure_handling, ) elif migration_mode in ( @@ -165,8 +151,6 @@ def meta_get( result = self._origin_client.meta_get( key=key, flags=flags, - int_flags=int_flags, - token_flags=token_flags, failure_handling=failure_handling, ) if isinstance(result, Value) and self._should_populate_read(migration_mode): @@ -181,8 +165,6 @@ def meta_get( return self._origin_client.meta_get( key=key, flags=flags, - int_flags=int_flags, - token_flags=token_flags, failure_handling=failure_handling, ) @@ -191,9 +173,7 @@ def meta_set( key: Key, value: Any, ttl: int, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> WriteResponse: origin_response = destination_response = None @@ -204,8 +184,6 @@ def meta_set( value=value, ttl=ttl, flags=flags, - int_flags=int_flags, - token_flags=token_flags, failure_handling=failure_handling, ) if migration_mode > MigrationMode.ONLY_ORIGIN: @@ -214,8 +192,6 @@ def meta_set( value=value, ttl=ttl, flags=flags, - int_flags=int_flags, - token_flags=token_flags, failure_handling=failure_handling, ) if migration_mode >= MigrationMode.USE_DESTINATION_UPDATE_ORIGIN: @@ -228,9 +204,7 @@ def meta_set( def meta_delete( self, key: Key, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> WriteResponse: origin_response = destination_response = None @@ -239,16 +213,12 @@ def meta_delete( origin_response = self._origin_client.meta_delete( key=key, flags=flags, - int_flags=int_flags, - token_flags=token_flags, failure_handling=failure_handling, ) if migration_mode > MigrationMode.ONLY_ORIGIN: destination_response = self._destination_client.meta_delete( key=key, flags=flags, - int_flags=int_flags, - token_flags=token_flags, failure_handling=failure_handling, ) if migration_mode >= MigrationMode.USE_DESTINATION_UPDATE_ORIGIN: @@ -261,9 +231,7 @@ def meta_delete( def meta_arithmetic( self, key: Key, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> WriteResponse: """ @@ -277,16 +245,12 @@ def meta_arithmetic( return self._destination_client.meta_arithmetic( key=key, flags=flags, - int_flags=int_flags, - token_flags=token_flags, failure_handling=failure_handling, ) else: return self._origin_client.meta_arithmetic( key=key, flags=flags, - int_flags=int_flags, - token_flags=token_flags, failure_handling=failure_handling, ) diff --git a/src/meta_memcache/interfaces/executor.py b/src/meta_memcache/interfaces/executor.py index 3a575ae..30a587b 100644 --- a/src/meta_memcache/interfaces/executor.py +++ b/src/meta_memcache/interfaces/executor.py @@ -1,15 +1,14 @@ -from typing import Dict, List, Optional, Protocol, Set, Tuple +from typing import Dict, List, Optional, Protocol, Tuple + from meta_memcache.connection.pool import ConnectionPool from meta_memcache.events.write_failure_event import WriteFailureEvent from meta_memcache.protocol import ( - Flag, - IntFlag, Key, MaybeValue, MemcacheResponse, MetaCommand, - TokenFlag, + RequestFlags, ) @@ -20,9 +19,7 @@ def exec_on_pool( command: MetaCommand, key: Key, value: MaybeValue, - flags: Optional[Set[Flag]], - int_flags: Optional[Dict[IntFlag, int]], - token_flags: Optional[Dict[TokenFlag, bytes]], + flags: Optional[RequestFlags], track_write_failures: bool, raise_on_server_error: Optional[bool] = None, ) -> MemcacheResponse: @@ -38,9 +35,7 @@ def exec_multi_on_pool( pool: ConnectionPool, command: MetaCommand, key_values: List[Tuple[Key, MaybeValue]], - flags: Optional[Set[Flag]], - int_flags: Optional[Dict[IntFlag, int]], - token_flags: Optional[Dict[TokenFlag, bytes]], + flags: Optional[RequestFlags], track_write_failures: bool, raise_on_server_error: Optional[bool] = None, ) -> Dict[Key, MemcacheResponse]: diff --git a/src/meta_memcache/interfaces/meta_commands.py b/src/meta_memcache/interfaces/meta_commands.py index 754feb9..0b8c441 100644 --- a/src/meta_memcache/interfaces/meta_commands.py +++ b/src/meta_memcache/interfaces/meta_commands.py @@ -1,13 +1,11 @@ -from typing import Any, Dict, List, Optional, Protocol, Set +from typing import Any, Dict, List, Optional, Protocol from meta_memcache.interfaces.router import FailureHandling, DEFAULT_FAILURE_HANDLING from meta_memcache.protocol import ( - Flag, - IntFlag, Key, ReadResponse, - TokenFlag, WriteResponse, + RequestFlags, ) @@ -15,18 +13,14 @@ class MetaCommandsProtocol(Protocol): def meta_multiget( self, keys: List[Key], - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> Dict[Key, ReadResponse]: ... # pragma: no cover def meta_get( self, key: Key, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> ReadResponse: ... # pragma: no cover @@ -35,26 +29,20 @@ def meta_set( key: Key, value: Any, ttl: int, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> WriteResponse: ... # pragma: no cover def meta_delete( self, key: Key, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> WriteResponse: ... # pragma: no cover def meta_arithmetic( self, key: Key, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> WriteResponse: ... # pragma: no cover diff --git a/src/meta_memcache/interfaces/router.py b/src/meta_memcache/interfaces/router.py index 0589caf..ce10fe1 100644 --- a/src/meta_memcache/interfaces/router.py +++ b/src/meta_memcache/interfaces/router.py @@ -1,17 +1,16 @@ -from typing import Dict, List, NamedTuple, Optional, Protocol, Set +from typing import Dict, List, NamedTuple, Optional, Protocol + from meta_memcache.configuration import ServerAddress from meta_memcache.connection.pool import PoolCounters from meta_memcache.interfaces.executor import Executor from meta_memcache.protocol import ( - Flag, - IntFlag, Key, MaybeValue, MaybeValues, MemcacheResponse, MetaCommand, - TokenFlag, + RequestFlags, ) @@ -34,9 +33,7 @@ def exec( command: MetaCommand, key: Key, value: MaybeValue = None, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> MemcacheResponse: """ @@ -52,9 +49,7 @@ def exec_multi( command: MetaCommand, keys: List[Key], values: MaybeValues = None, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> Dict[Key, MemcacheResponse]: """ diff --git a/src/meta_memcache/protocol.py b/src/meta_memcache/protocol.py index 37302db..138b1ef 100644 --- a/src/meta_memcache/protocol.py +++ b/src/meta_memcache/protocol.py @@ -1,8 +1,18 @@ from dataclasses import dataclass from enum import Enum, IntEnum -from typing import Any, Dict, List, Optional, Union - -from meta_memcache_socket import ResponseFlags +from typing import Any, List, Optional, Union + +from meta_memcache_socket import ( # noqa: F401 + ResponseFlags, + RequestFlags as RequestFlags, + SET_MODE_ADD, + SET_MODE_APPEND, + SET_MODE_PREPEND, + SET_MODE_REPLACE, + SET_MODE_SET, + MA_MODE_INC as MA_MODE_INC, + MA_MODE_DEC as MA_MODE_DEC, +) ENDL = b"\r\n" NOOP: bytes = b"mn" + ENDL @@ -39,57 +49,11 @@ class MetaCommand(Enum): class SetMode(Enum): - SET = b"S" # Default - ADD = b"E" # Add if item does NOT EXIST, else LRU bump and return NS - APPEND = b"A" # If item exists, append the new value to its data. - PREPEND = b"P" # If item exists, prepend the new value to its data. - REPLACE = b"R" # Set only if item already exists. - - -class Flag(Enum): - BINARY = b"b" - NOREPLY = b"q" - RETURN_CLIENT_FLAG = b"f" - RETURN_CAS_TOKEN = b"c" - RETURN_VALUE = b"v" - RETURN_TTL = b"t" - RETURN_SIZE = b"s" - RETURN_LAST_ACCESS = b"l" - RETURN_FETCHED = b"h" - RETURN_KEY = b"k" - NO_UPDATE_LRU = b"u" - MARK_STALE = b"I" - - -class IntFlag(Enum): - CACHE_TTL = b"T" - RECACHE_TTL = b"R" - MISS_LEASE_TTL = b"N" - SET_CLIENT_FLAG = b"F" - MA_INITIAL_VALUE = b"J" - MA_DELTA_VALUE = b"D" - CAS_TOKEN = b"C" - - -class TokenFlag(Enum): - OPAQUE = b"O" - # 'M' (mode switch): - # * Meta Arithmetic: - # - I or +: increment - # - D or -: decrement - # * Meta Set: See SetMode Enum above - # - E: "add" command. LRU bump and return NS if item exists. Else add. - # - A: "append" command. If item exists, append the new value to its data. - # - P: "prepend" command. If item exists, prepend the new value to its data. - # - R: "replace" command. Set only if item already exists. - # - S: "set" command. The default mode, added for completeness. - MODE = b"M" - - -# Store maps of byte values (int) to enum value -flag_values: Dict[int, Flag] = {f.value[0]: f for f in Flag} -int_flags_values: Dict[int, IntFlag] = {f.value[0]: f for f in IntFlag} -token_flags_values: Dict[int, TokenFlag] = {f.value[0]: f for f in TokenFlag} + SET = SET_MODE_SET # Default + ADD = SET_MODE_ADD # Add if item does NOT EXIST, else LRU bump and return NS + APPEND = SET_MODE_APPEND # If item exists, append the new value to its data. + PREPEND = SET_MODE_PREPEND # If item exists, prepend the new value to its data. + REPLACE = SET_MODE_REPLACE # Set only if item already exists. @dataclass @@ -104,19 +68,11 @@ class Miss(MemcacheResponse): pass -# Response flags -EMPTY_RESPONSE_FLAGS = ResponseFlags() - - @dataclass class Success(MemcacheResponse): __slots__ = ("flags",) flags: ResponseFlags - @classmethod - def default(cls) -> "Success": - return cls(flags=ResponseFlags()) - @dataclass class Value(Success): @@ -168,10 +124,3 @@ def get_store_success_response_header(version: ServerVersion) -> bytes: if version == ServerVersion.AWS_1_6_6: return b"OK" return b"HD" - - -def encode_size(size: int, version: ServerVersion) -> bytes: - if version == ServerVersion.AWS_1_6_6: - return b"S" + str(size).encode("ascii") - else: - return str(size).encode("ascii") diff --git a/src/meta_memcache/routers/default.py b/src/meta_memcache/routers/default.py index ee25985..d95d9c5 100644 --- a/src/meta_memcache/routers/default.py +++ b/src/meta_memcache/routers/default.py @@ -1,5 +1,6 @@ from collections import defaultdict -from typing import Callable, DefaultDict, Dict, List, Optional, Set, Tuple +from typing import Callable, DefaultDict, Dict, List, Optional, Tuple + from meta_memcache.configuration import ServerAddress from meta_memcache.connection.pool import ConnectionPool, PoolCounters @@ -7,14 +8,12 @@ from meta_memcache.interfaces.executor import Executor from meta_memcache.interfaces.router import DEFAULT_FAILURE_HANDLING, FailureHandling from meta_memcache.protocol import ( - Flag, - IntFlag, Key, MaybeValue, MaybeValues, MemcacheResponse, MetaCommand, - TokenFlag, + RequestFlags, ) @@ -32,9 +31,7 @@ def exec( command: MetaCommand, key: Key, value: MaybeValue = None, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> MemcacheResponse: """ @@ -49,8 +46,6 @@ def exec( key=key, value=value, flags=flags, - int_flags=int_flags, - token_flags=token_flags, track_write_failures=failure_handling.track_write_failures, raise_on_server_error=failure_handling.raise_on_server_error, ) @@ -60,9 +55,7 @@ def exec_multi( command: MetaCommand, keys: List[Key], values: MaybeValues = None, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> Dict[Key, MemcacheResponse]: """ @@ -78,8 +71,6 @@ def exec_multi( command=command, key_values=key_values, flags=flags, - int_flags=int_flags, - token_flags=token_flags, track_write_failures=failure_handling.track_write_failures, raise_on_server_error=failure_handling.raise_on_server_error, ) diff --git a/src/meta_memcache/routers/ephemeral.py b/src/meta_memcache/routers/ephemeral.py index e13fde0..291ec4a 100644 --- a/src/meta_memcache/routers/ephemeral.py +++ b/src/meta_memcache/routers/ephemeral.py @@ -1,20 +1,18 @@ -from typing import Dict, List, Optional, Set +from typing import Dict, List, Optional from meta_memcache.connection.providers import ConnectionPoolProvider from meta_memcache.interfaces.executor import Executor from meta_memcache.interfaces.router import DEFAULT_FAILURE_HANDLING, FailureHandling from meta_memcache.protocol import ( - Flag, - IntFlag, Key, MaybeValue, MaybeValues, MemcacheResponse, MetaCommand, - TokenFlag, + RequestFlags, ) from meta_memcache.routers.default import DefaultRouter -from meta_memcache.routers.helpers import adjust_int_flags_for_max_ttl +from meta_memcache.routers.helpers import adjust_flags_for_max_ttl class EphemeralRouter(DefaultRouter): @@ -52,18 +50,14 @@ def exec( command: MetaCommand, key: Key, value: MaybeValue = None, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> MemcacheResponse: return super().exec( command=command, key=key, value=value, - flags=flags, - int_flags=adjust_int_flags_for_max_ttl(int_flags, self._max_ttl), - token_flags=token_flags, + flags=adjust_flags_for_max_ttl(flags, self._max_ttl), failure_handling=failure_handling, ) @@ -72,17 +66,13 @@ def exec_multi( command: MetaCommand, keys: List[Key], values: MaybeValues = None, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> Dict[Key, MemcacheResponse]: return super().exec_multi( command=command, keys=keys, values=values, - flags=flags, - int_flags=adjust_int_flags_for_max_ttl(int_flags, self._max_ttl), - token_flags=token_flags, + flags=adjust_flags_for_max_ttl(flags, self._max_ttl), failure_handling=failure_handling, ) diff --git a/src/meta_memcache/routers/gutter.py b/src/meta_memcache/routers/gutter.py index 91e8eb0..0f32511 100644 --- a/src/meta_memcache/routers/gutter.py +++ b/src/meta_memcache/routers/gutter.py @@ -1,21 +1,19 @@ -from typing import Dict, List, Optional, Set +from typing import Dict, List, Optional from meta_memcache.connection.providers import ConnectionPoolProvider from meta_memcache.errors import MemcacheServerError from meta_memcache.interfaces.executor import Executor from meta_memcache.interfaces.router import DEFAULT_FAILURE_HANDLING, FailureHandling from meta_memcache.protocol import ( - Flag, - IntFlag, Key, MaybeValue, MaybeValues, MemcacheResponse, MetaCommand, - TokenFlag, + RequestFlags, ) from meta_memcache.routers.default import DefaultRouter -from meta_memcache.routers.helpers import adjust_int_flags_for_max_ttl +from meta_memcache.routers.helpers import adjust_flags_for_max_ttl class GutterRouter(DefaultRouter): @@ -38,9 +36,7 @@ def exec( command: MetaCommand, key: Key, value: MaybeValue = None, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> MemcacheResponse: """ @@ -57,8 +53,6 @@ def exec( key=key, value=value, flags=flags, - int_flags=int_flags, - token_flags=token_flags, # We always want to raise on server errors so we can # try the gutter pool raise_on_server_error=True, @@ -67,15 +61,13 @@ def exec( ) except MemcacheServerError: # Override TTLs > than gutter TTL - int_flags = adjust_int_flags_for_max_ttl(int_flags, self._gutter_ttl) + flags = adjust_flags_for_max_ttl(flags, self._gutter_ttl) return self.executor.exec_on_pool( pool=self.gutter_pool_provider.get_pool(key), command=command, key=key, value=value, flags=flags, - int_flags=int_flags, - token_flags=token_flags, # Respect the raise_on_server_error flag if the gutter pool also # fails raise_on_server_error=failure_handling.raise_on_server_error, @@ -89,9 +81,7 @@ def exec_multi( command: MetaCommand, keys: List[Key], values: MaybeValues = None, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> Dict[Key, MemcacheResponse]: """ @@ -110,8 +100,6 @@ def exec_multi( command=command, key_values=key_values, flags=flags, - int_flags=int_flags, - token_flags=token_flags, # We always want to raise on server errors so we can # try the gutter pool raise_on_server_error=True, @@ -126,7 +114,7 @@ def exec_multi( gutter_values.append(value) if gutter_keys: # Override TTLs > than gutter TTL - int_flags = adjust_int_flags_for_max_ttl(int_flags, self._gutter_ttl) + flags = adjust_flags_for_max_ttl(flags, self._gutter_ttl) for pool, key_values in self._exec_multi_prepare_pool_map( self.gutter_pool_provider.get_pool, gutter_keys, gutter_values ).items(): @@ -136,8 +124,6 @@ def exec_multi( command=command, key_values=key_values, flags=flags, - int_flags=int_flags, - token_flags=token_flags, # Respect the raise_on_server_error flag if the gutter pool also # fails raise_on_server_error=failure_handling.raise_on_server_error, diff --git a/src/meta_memcache/routers/helpers.py b/src/meta_memcache/routers/helpers.py index f8f1bf3..f9ebc29 100644 --- a/src/meta_memcache/routers/helpers.py +++ b/src/meta_memcache/routers/helpers.py @@ -1,23 +1,24 @@ -from typing import Dict, Optional +from typing import Optional -from meta_memcache.protocol import IntFlag +from meta_memcache.protocol import RequestFlags -def adjust_int_flags_for_max_ttl( - int_flags: Optional[Dict[IntFlag, int]], +def _adjust_ttl(ttl: Optional[int], max_ttl: int) -> Optional[int]: + if ttl is not None and (ttl == 0 or ttl > max_ttl): + return max_ttl + return ttl + + +def adjust_flags_for_max_ttl( + flags: Optional[RequestFlags], max_ttl: int, -) -> Optional[Dict[IntFlag, int]]: +) -> Optional[RequestFlags]: """ Override TTLs > than `max_ttl` """ - if int_flags: - for flag in ( - IntFlag.CACHE_TTL, - IntFlag.RECACHE_TTL, - IntFlag.MISS_LEASE_TTL, - ): - ttl = int_flags.get(flag) - if ttl is not None and (ttl == 0 or ttl > max_ttl): - int_flags[flag] = max_ttl + if flags: + flags.cache_ttl = _adjust_ttl(flags.cache_ttl, max_ttl) + flags.recache_ttl = _adjust_ttl(flags.recache_ttl, max_ttl) + flags.vivify_on_miss_ttl = _adjust_ttl(flags.vivify_on_miss_ttl, max_ttl) - return int_flags + return flags diff --git a/src/meta_memcache/settings.py b/src/meta_memcache/settings.py index 9e9a207..cecbbfd 100644 --- a/src/meta_memcache/settings.py +++ b/src/meta_memcache/settings.py @@ -5,4 +5,7 @@ DEFAULT_READ_BUFFER_SIZE = 4096 -MAX_KEY_SIZE = 250 +# Max key is 250, but when using binary keys will be b64 encoded +# so take more space. Keys longer than this will be hashed, so +# it's not a problem. +MAX_KEY_SIZE = 187 diff --git a/tests/cache_client_test.py b/tests/cache_client_test.py index 9e376e9..e224f6f 100644 --- a/tests/cache_client_test.py +++ b/tests/cache_client_test.py @@ -12,7 +12,7 @@ ) from meta_memcache.connection.pool import ConnectionPool, PoolCounters from meta_memcache.errors import MemcacheServerError -from meta_memcache.protocol import NOOP, Flag, IntFlag +from meta_memcache.protocol import NOOP, RequestFlags from meta_memcache.settings import DEFAULT_MARK_DOWN_PERIOD_S @@ -167,10 +167,10 @@ def connect(server_address: Tuple[str, int]) -> None: cache_client.meta_multiget( keys=[Key("bar"), Key("foo")], - flags={ - Flag.NOREPLY, - }, - int_flags={IntFlag.CACHE_TTL: 1000}, + flags=RequestFlags( + no_reply=True, + cache_ttl=1000, + ), ) get_pool.assert_has_calls([call(Key(key="bar")), call(Key(key="foo"))]) get_gutter_pool.assert_called_once_with(Key("foo")) @@ -194,10 +194,10 @@ def connect(server_address: Tuple[str, int]) -> None: cache_client.meta_multiget( keys=[Key("bar"), Key("foo")], - flags={ - Flag.NOREPLY, - }, - int_flags={IntFlag.CACHE_TTL: 1000}, + flags=RequestFlags( + no_reply=True, + cache_ttl=1000, + ), ) get_pool.assert_has_calls([call(Key(key="bar")), call(Key(key="foo"))]) get_gutter_pool.assert_called_once_with(Key("foo")) @@ -220,10 +220,10 @@ def connect(server_address: Tuple[str, int]) -> None: cache_client.meta_multiget( keys=[Key("bar"), Key("foo")], - flags={ - Flag.NOREPLY, - }, - int_flags={IntFlag.CACHE_TTL: 1000}, + flags=RequestFlags( + no_reply=True, + cache_ttl=1000, + ), ) get_pool.assert_has_calls([call(Key(key="bar")), call(Key(key="foo"))]) get_gutter_pool.assert_not_called() diff --git a/tests/commands_test.py b/tests/commands_test.py index 3bd2241..cafb033 100644 --- a/tests/commands_test.py +++ b/tests/commands_test.py @@ -28,10 +28,9 @@ Miss, NotStored, ResponseFlags, + RequestFlags, ServerVersion, Success, - IntFlag, - TokenFlag, Value, ) from meta_memcache.routers.default import DefaultRouter @@ -243,7 +242,7 @@ def test_set_cmd( cache_client.set(key=Key("foo"), value=b"123", ttl=300, cas_token=666) memcache_socket.sendall.assert_called_once_with( - b"ms foo 3 T300 C666 F16\r\n123\r\n", with_noop=False + b"ms foo 3 T300 F16 C666\r\n123\r\n", with_noop=False ) memcache_socket.get_response.assert_called_once_with() memcache_socket.sendall.reset_mock() @@ -253,7 +252,7 @@ def test_set_cmd( key=Key("foo"), value=b"123", ttl=300, cas_token=666, stale_policy=StalePolicy() ) memcache_socket.sendall.assert_called_once_with( - b"ms foo 3 T300 C666 F16\r\n123\r\n", with_noop=False + b"ms foo 3 T300 F16 C666\r\n123\r\n", with_noop=False ) memcache_socket.get_response.assert_called_once_with() memcache_socket.sendall.reset_mock() @@ -267,7 +266,7 @@ def test_set_cmd( stale_policy=StalePolicy(mark_stale_on_cas_mismatch=True), ) memcache_socket.sendall.assert_called_once_with( - b"ms foo 3 I T300 C666 F16\r\n123\r\n", with_noop=False + b"ms foo 3 I T300 F16 C666\r\n123\r\n", with_noop=False ) memcache_socket.get_response.assert_called_once_with() memcache_socket.sendall.reset_mock() @@ -309,9 +308,7 @@ def test_refill( key=Key(key="foo"), value="bar", ttl=300, - flags=set(), - int_flags={IntFlag.CACHE_TTL: 300}, - token_flags={TokenFlag.MODE: SetMode.ADD.value}, + flags=RequestFlags(cache_ttl=300, mode=SetMode.ADD.value), failure_handling=FailureHandling(track_write_failures=False), ) @@ -560,7 +557,7 @@ def test_get_cmd(memcache_socket: MemcacheSocket, cache_client: CacheClient) -> ) assert_called_once_with_command( memcache_socket.sendall, - b"mg lCV3WxKxtWrdY4s1+R710+9J b t l v h f R30 T300\r\n", + b"mg w7puw63Dp29k4o23 b t l v h f R30 T300\r\n", with_noop=False, ) memcache_socket.sendall.reset_mock() @@ -1186,7 +1183,7 @@ def test_delta_cmd(memcache_socket: MemcacheSocket, cache_client: CacheClient) - cache_client.delta(key=Key("foo"), delta=1, refresh_ttl=60, no_reply=True) memcache_socket.sendall.assert_called_once_with( - b"ma foo q D1 T60\r\n", with_noop=True + b"ma foo q T60 D1\r\n", with_noop=True ) memcache_socket.sendall.reset_mock() @@ -1205,7 +1202,7 @@ def test_delta_cmd(memcache_socket: MemcacheSocket, cache_client: CacheClient) - cas_token=123, ) memcache_socket.sendall.assert_called_once_with( - b"ma foo q D1 C123 J10 N60\r\n", with_noop=True + b"ma foo q N60 J10 D1 C123\r\n", with_noop=True ) memcache_socket.sendall.reset_mock() @@ -1228,7 +1225,7 @@ def test_delta_cmd(memcache_socket: MemcacheSocket, cache_client: CacheClient) - ) assert result is None memcache_socket.sendall.assert_called_once_with( - b"ma foo v D1 J0 N60\r\n", with_noop=False + b"ma foo v N60 J0 D1\r\n", with_noop=False ) memcache_socket.sendall.reset_mock() memcache_socket.get_response.reset_mock() @@ -1258,7 +1255,7 @@ def test_delta_cmd(memcache_socket: MemcacheSocket, cache_client: CacheClient) - ) assert result == 10 memcache_socket.sendall.assert_called_once_with( - b"ma foo v D1 J0 N60\r\n", with_noop=False + b"ma foo v N60 J0 D1\r\n", with_noop=False ) memcache_socket.sendall.reset_mock() memcache_socket.get_response.reset_mock() diff --git a/tests/ephemeral_cache_client_test.py b/tests/ephemeral_cache_client_test.py index ddc2a30..e1249a3 100644 --- a/tests/ephemeral_cache_client_test.py +++ b/tests/ephemeral_cache_client_test.py @@ -1,5 +1,5 @@ from unittest.mock import call -from meta_memcache.protocol import NOOP, Flag, IntFlag +from meta_memcache.protocol import NOOP, RequestFlags from pytest_mock import MockerFixture @@ -29,10 +29,10 @@ def test_ephemeral_cache_client(mocker: MockerFixture) -> None: cache_client.meta_multiget( keys=[Key("bar"), Key("foo")], - flags={ - Flag.NOREPLY, - }, - int_flags={IntFlag.CACHE_TTL: 1000}, + flags=RequestFlags( + no_reply=True, + cache_ttl=1000, + ), ) c.sendall.assert_has_calls([call(b"mg bar q T60\r\n"), call(b"mg foo q T60\r\n")]) c.sendall.reset_mock() diff --git a/tests/migrating_cache_client_test.py b/tests/migrating_cache_client_test.py index 9e1ceef..aec15e1 100644 --- a/tests/migrating_cache_client_test.py +++ b/tests/migrating_cache_client_test.py @@ -4,12 +4,12 @@ import pytest from meta_memcache import ( CacheClient, - IntFlag, Key, SetMode, Value, WriteFailureEvent, ResponseFlags, + RequestFlags, ) from meta_memcache.extras.migrating_cache_client import ( MigratingCacheClient, @@ -168,9 +168,7 @@ def test_migration_mode_origin_only( key=Key(key="foo", routing_key=None, is_unicode=False), value="bar", ttl=10, - flags=set(), - int_flags={IntFlag.CACHE_TTL: 10}, - token_flags=None, + flags=RequestFlags(cache_ttl=10), failure_handling=DEFAULT_FAILURE_HANDLING, ) destination_client.meta_set.assert_not_called() @@ -179,9 +177,7 @@ def test_migration_mode_origin_only( migration_client_origin_only.delete(key="foo") origin_client.meta_delete.assert_called_once_with( key=Key(key="foo", routing_key=None, is_unicode=False), - flags=set(), - int_flags={}, - token_flags=None, + flags=RequestFlags(), failure_handling=DEFAULT_FAILURE_HANDLING, ) destination_client.meta_delete.assert_not_called() @@ -190,9 +186,7 @@ def test_migration_mode_origin_only( migration_client_origin_only.delta(key="foo", delta=1) origin_client.meta_arithmetic.assert_called_once_with( key=Key(key="foo", routing_key=None, is_unicode=False), - flags=set(), - int_flags={IntFlag.MA_DELTA_VALUE: 1}, - token_flags={}, + flags=RequestFlags(ma_delta_value=1), failure_handling=DEFAULT_FAILURE_HANDLING, ) destination_client.meta_arithmetic.assert_not_called() @@ -231,9 +225,7 @@ def test_migration_mode_destination_only( key=Key(key="foo", routing_key=None, is_unicode=False), value="bar", ttl=10, - flags=set(), - int_flags={IntFlag.CACHE_TTL: 10}, - token_flags=None, + flags=RequestFlags(cache_ttl=10), failure_handling=DEFAULT_FAILURE_HANDLING, ) @@ -242,9 +234,7 @@ def test_migration_mode_destination_only( origin_client.meta_delete.assert_not_called() destination_client.meta_delete.assert_called_once_with( key=Key(key="foo", routing_key=None, is_unicode=False), - flags=set(), - int_flags={}, - token_flags=None, + flags=RequestFlags(), failure_handling=DEFAULT_FAILURE_HANDLING, ) @@ -253,9 +243,7 @@ def test_migration_mode_destination_only( origin_client.meta_arithmetic.assert_not_called() destination_client.meta_arithmetic.assert_called_once_with( key=Key(key="foo", routing_key=None, is_unicode=False), - flags=set(), - int_flags={IntFlag.MA_DELTA_VALUE: 1}, - token_flags={}, + flags=RequestFlags(ma_delta_value=1), failure_handling=DEFAULT_FAILURE_HANDLING, ) @@ -296,18 +284,14 @@ def test_migration_mode_populate_writes( key=Key(key="foo", routing_key=None, is_unicode=False), value="bar", ttl=10, - flags=set(), - int_flags={IntFlag.CACHE_TTL: 10}, - token_flags=None, + flags=RequestFlags(cache_ttl=10), failure_handling=DEFAULT_FAILURE_HANDLING, ) destination_client.meta_set.assert_called_once_with( key=Key(key="foo", routing_key=None, is_unicode=False), value="bar", ttl=10, - flags=set(), - int_flags={IntFlag.CACHE_TTL: 10}, - token_flags=None, + flags=RequestFlags(cache_ttl=10), failure_handling=DEFAULT_FAILURE_HANDLING, ) @@ -315,16 +299,12 @@ def test_migration_mode_populate_writes( migration_client.delete(key="foo") origin_client.meta_delete.assert_called_once_with( key=Key(key="foo", routing_key=None, is_unicode=False), - flags=set(), - int_flags={}, - token_flags=None, + flags=RequestFlags(), failure_handling=DEFAULT_FAILURE_HANDLING, ) destination_client.meta_delete.assert_called_once_with( key=Key(key="foo", routing_key=None, is_unicode=False), - flags=set(), - int_flags={}, - token_flags=None, + flags=RequestFlags(), failure_handling=DEFAULT_FAILURE_HANDLING, ) @@ -332,9 +312,7 @@ def test_migration_mode_populate_writes( migration_client.delta(key="foo", delta=1) origin_client.meta_arithmetic.assert_called_once_with( key=Key(key="foo", routing_key=None, is_unicode=False), - flags=set(), - int_flags={IntFlag.MA_DELTA_VALUE: 1}, - token_flags={}, + flags=RequestFlags(ma_delta_value=1), failure_handling=DEFAULT_FAILURE_HANDLING, ) destination_client.meta_arithmetic.assert_not_called() @@ -459,18 +437,14 @@ def test_migration_mode_populate_writes_and_reads_1pct( key=Key(key="foo", routing_key=None, is_unicode=False), value="bar", ttl=10, - flags=set(), - int_flags={IntFlag.CACHE_TTL: 10}, - token_flags=None, + flags=RequestFlags(cache_ttl=10), failure_handling=DEFAULT_FAILURE_HANDLING, ) destination_client.meta_set.assert_called_once_with( key=Key(key="foo", routing_key=None, is_unicode=False), value="bar", ttl=10, - flags=set(), - int_flags={IntFlag.CACHE_TTL: 10}, - token_flags=None, + flags=RequestFlags(cache_ttl=10), failure_handling=DEFAULT_FAILURE_HANDLING, ) @@ -478,16 +452,12 @@ def test_migration_mode_populate_writes_and_reads_1pct( migration_client.delete(key="foo") origin_client.meta_delete.assert_called_once_with( key=Key(key="foo", routing_key=None, is_unicode=False), - flags=set(), - int_flags={}, - token_flags=None, + flags=RequestFlags(), failure_handling=DEFAULT_FAILURE_HANDLING, ) destination_client.meta_delete.assert_called_once_with( key=Key(key="foo", routing_key=None, is_unicode=False), - flags=set(), - int_flags={}, - token_flags=None, + flags=RequestFlags(), failure_handling=DEFAULT_FAILURE_HANDLING, ) @@ -495,9 +465,7 @@ def test_migration_mode_populate_writes_and_reads_1pct( migration_client.delta(key="foo", delta=1) origin_client.meta_arithmetic.assert_called_once_with( key=Key(key="foo", routing_key=None, is_unicode=False), - flags=set(), - int_flags={IntFlag.MA_DELTA_VALUE: 1}, - token_flags={}, + flags=RequestFlags(ma_delta_value=1), failure_handling=DEFAULT_FAILURE_HANDLING, ) destination_client.meta_arithmetic.assert_not_called() @@ -577,18 +545,14 @@ def test_migration_mode_populate_writes_and_reads_10pct( key=Key(key="foo", routing_key=None, is_unicode=False), value="bar", ttl=10, - flags=set(), - int_flags={IntFlag.CACHE_TTL: 10}, - token_flags=None, + flags=RequestFlags(cache_ttl=10), failure_handling=DEFAULT_FAILURE_HANDLING, ) destination_client.meta_set.assert_called_once_with( key=Key(key="foo", routing_key=None, is_unicode=False), value="bar", ttl=10, - flags=set(), - int_flags={IntFlag.CACHE_TTL: 10}, - token_flags=None, + flags=RequestFlags(cache_ttl=10), failure_handling=DEFAULT_FAILURE_HANDLING, ) @@ -596,16 +560,12 @@ def test_migration_mode_populate_writes_and_reads_10pct( migration_client.delete(key="foo") origin_client.meta_delete.assert_called_once_with( key=Key(key="foo", routing_key=None, is_unicode=False), - flags=set(), - int_flags={}, - token_flags=None, + flags=RequestFlags(), failure_handling=DEFAULT_FAILURE_HANDLING, ) destination_client.meta_delete.assert_called_once_with( key=Key(key="foo", routing_key=None, is_unicode=False), - flags=set(), - int_flags={}, - token_flags=None, + flags=RequestFlags(), failure_handling=DEFAULT_FAILURE_HANDLING, ) @@ -613,9 +573,7 @@ def test_migration_mode_populate_writes_and_reads_10pct( migration_client.delta(key="foo", delta=1) origin_client.meta_arithmetic.assert_called_once_with( key=Key(key="foo", routing_key=None, is_unicode=False), - flags=set(), - int_flags={IntFlag.MA_DELTA_VALUE: 1}, - token_flags={}, + flags=RequestFlags(ma_delta_value=1), failure_handling=DEFAULT_FAILURE_HANDLING, ) destination_client.meta_arithmetic.assert_not_called() @@ -660,18 +618,14 @@ def test_migration_mode_use_destination_update_origin( key=Key(key="foo", routing_key=None, is_unicode=False), value="bar", ttl=10, - flags=set(), - int_flags={IntFlag.CACHE_TTL: 10}, - token_flags=None, + flags=RequestFlags(cache_ttl=10), failure_handling=DEFAULT_FAILURE_HANDLING, ) destination_client.meta_set.assert_called_once_with( key=Key(key="foo", routing_key=None, is_unicode=False), value="bar", ttl=10, - flags=set(), - int_flags={IntFlag.CACHE_TTL: 10}, - token_flags=None, + flags=RequestFlags(cache_ttl=10), failure_handling=DEFAULT_FAILURE_HANDLING, ) @@ -679,16 +633,12 @@ def test_migration_mode_use_destination_update_origin( migration_client.delete(key="foo") origin_client.meta_delete.assert_called_once_with( key=Key(key="foo", routing_key=None, is_unicode=False), - flags=set(), - int_flags={}, - token_flags=None, + flags=RequestFlags(), failure_handling=DEFAULT_FAILURE_HANDLING, ) destination_client.meta_delete.assert_called_once_with( key=Key(key="foo", routing_key=None, is_unicode=False), - flags=set(), - int_flags={}, - token_flags=None, + flags=RequestFlags(), failure_handling=DEFAULT_FAILURE_HANDLING, ) @@ -697,9 +647,7 @@ def test_migration_mode_use_destination_update_origin( origin_client.meta_arithmetic.assert_not_called() destination_client.meta_arithmetic.assert_called_once_with( key=Key(key="foo", routing_key=None, is_unicode=False), - flags=set(), - int_flags={IntFlag.MA_DELTA_VALUE: 1}, - token_flags={}, + flags=RequestFlags(ma_delta_value=1), failure_handling=DEFAULT_FAILURE_HANDLING, ) diff --git a/tests/probabilistic_hot_cache_test.py b/tests/probabilistic_hot_cache_test.py index 4e02fcf..afb5496 100644 --- a/tests/probabilistic_hot_cache_test.py +++ b/tests/probabilistic_hot_cache_test.py @@ -1,4 +1,4 @@ -from typing import Dict, List, Optional, Set +from typing import Dict, List, Optional from unittest.mock import Mock from prometheus_client import CollectorRegistry @@ -6,23 +6,21 @@ import pytest -from meta_memcache import CacheClient, IntFlag, Key, Value +from meta_memcache import CacheClient, Key, Value from meta_memcache.errors import MemcacheError from meta_memcache.extras.probabilistic_hot_cache import ( CachedValue, ProbabilisticHotCache, ) from meta_memcache.metrics.prometheus import PrometheusMetricsCollector -from meta_memcache.protocol import Flag, Miss, ReadResponse, TokenFlag, ResponseFlags +from meta_memcache.protocol import Miss, ReadResponse, ResponseFlags, RequestFlags @pytest.fixture def client() -> Mock: def meta_get( key: Key, - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> ReadResponse: if key.key.endswith("hot"): @@ -48,9 +46,7 @@ def meta_get( def meta_multiget( keys: List[Key], - flags: Optional[Set[Flag]] = None, - int_flags: Optional[Dict[IntFlag, int]] = None, - token_flags: Optional[Dict[TokenFlag, bytes]] = None, + flags: Optional[RequestFlags] = None, failure_handling: FailureHandling = DEFAULT_FAILURE_HANDLING, ) -> Dict[Key, ReadResponse]: return {key: meta_get(key=key) for key in keys} @@ -78,15 +74,13 @@ def random(monkeypatch) -> Mock: DEFAULT_FLAGS = { - "flags": { - Flag.RETURN_TTL, - Flag.RETURN_LAST_ACCESS, - Flag.RETURN_VALUE, - Flag.RETURN_FETCHED, - Flag.RETURN_CLIENT_FLAG, - }, - "int_flags": None, - "token_flags": None, + "flags": RequestFlags( + return_ttl=True, + return_last_access=True, + return_value=True, + return_fetched=True, + return_client_flag=True, + ), "failure_handling": DEFAULT_FAILURE_HANDLING, }