cachekit 0.20.0__tar.gz → 0.22.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. {cachekit-0.20.0 → cachekit-0.22.0}/Cargo.lock +106 -52
  2. {cachekit-0.20.0 → cachekit-0.22.0}/Cargo.toml +2 -21
  3. {cachekit-0.20.0 → cachekit-0.22.0}/PKG-INFO +28 -17
  4. {cachekit-0.20.0 → cachekit-0.22.0}/README.md +24 -11
  5. {cachekit-0.20.0 → cachekit-0.22.0}/pyproject.toml +16 -25
  6. {cachekit-0.20.0 → cachekit-0.22.0}/rust/Cargo.toml +4 -4
  7. {cachekit-0.20.0 → cachekit-0.22.0}/rust/Makefile +4 -7
  8. {cachekit-0.20.0 → cachekit-0.22.0}/rust/README.md +24 -11
  9. {cachekit-0.20.0 → cachekit-0.22.0}/rust/src/lib.rs +4 -5
  10. {cachekit-0.20.0 → cachekit-0.22.0}/rust/src/python_bindings.rs +0 -44
  11. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/__init__.py +8 -12
  12. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/backends/__init__.py +14 -3
  13. cachekit-0.22.0/src/cachekit/backends/_uninterrupted.py +38 -0
  14. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/backends/base.py +3 -1
  15. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/backends/base_config.py +2 -1
  16. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/backends/cachekitio/backend.py +462 -229
  17. cachekit-0.22.0/src/cachekit/backends/cachekitio/client.py +279 -0
  18. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/backends/cachekitio/config.py +6 -9
  19. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/backends/cachekitio/error_handler.py +44 -26
  20. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/backends/errors.py +19 -18
  21. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/backends/file/__init__.py +1 -1
  22. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/backends/file/backend.py +35 -12
  23. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/backends/file/config.py +2 -2
  24. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/backends/memcached/__init__.py +2 -1
  25. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/backends/memcached/backend.py +137 -27
  26. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/backends/memcached/config.py +6 -3
  27. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/backends/memcached/error_handler.py +26 -2
  28. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/backends/provider.py +37 -24
  29. cachekit-0.22.0/src/cachekit/backends/redis/__init__.py +17 -0
  30. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/backends/redis/backend.py +25 -3
  31. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/backends/redis/client.py +43 -11
  32. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/backends/redis/config.py +16 -8
  33. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/backends/redis/error_handler.py +9 -9
  34. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/backends/redis/provider.py +74 -30
  35. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/cache_handler.py +270 -108
  36. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/config/decorator.py +124 -85
  37. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/config/nested.py +34 -21
  38. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/config/settings.py +13 -19
  39. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/config/singleton.py +8 -6
  40. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/config/validation.py +100 -32
  41. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/decorators/intent.py +19 -5
  42. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/decorators/orchestrator.py +25 -4
  43. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/decorators/wrapper.py +995 -547
  44. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/hash_utils.py +63 -4
  45. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/health.py +6 -1
  46. cachekit-0.22.0/src/cachekit/hiredis_compat.py +98 -0
  47. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/interop.py +51 -5
  48. cachekit-0.22.0/src/cachekit/invalidation.py +483 -0
  49. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/key_generator.py +22 -1
  50. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/l1_cache.py +248 -106
  51. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/object_cache.py +200 -87
  52. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/reliability/__init__.py +1 -11
  53. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/reliability/async_metrics.py +344 -148
  54. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/reliability/circuit_breaker.py +162 -31
  55. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/serializers/__init__.py +4 -2
  56. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/serializers/arrow_serializer.py +41 -22
  57. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/serializers/auto_serializer.py +105 -39
  58. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/serializers/encryption_wrapper.py +82 -30
  59. cachekit-0.22.0/src/cachekit/serializers/wrapper.py +270 -0
  60. cachekit-0.20.0/src/cachekit/backends/cachekitio/client.py +0 -187
  61. cachekit-0.20.0/src/cachekit/backends/redis/__init__.py +0 -12
  62. cachekit-0.20.0/src/cachekit/hiredis_compat.py +0 -98
  63. cachekit-0.20.0/src/cachekit/reliability/profiles.py +0 -236
  64. cachekit-0.20.0/src/cachekit/serializers/wrapper.py +0 -169
  65. {cachekit-0.20.0 → cachekit-0.22.0}/LICENSE +0 -0
  66. {cachekit-0.20.0 → cachekit-0.22.0}/rust/TEST_EXPANSION_SUMMARY.md +0 -0
  67. {cachekit-0.20.0 → cachekit-0.22.0}/rust/src/msgpack_bounds.rs +0 -0
  68. {cachekit-0.20.0 → cachekit-0.22.0}/rust/tsan_suppressions.txt +0 -0
  69. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/backends/cachekitio/__init__.py +0 -0
  70. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/backends/cachekitio/session.py +0 -0
  71. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/config/__init__.py +0 -0
  72. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/decorators/__init__.py +0 -0
  73. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/decorators/local_wrapper.py +0 -0
  74. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/decorators/main.py +0 -0
  75. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/decorators/session.py +0 -0
  76. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/decorators/stats_context.py +0 -0
  77. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/decorators/tenant_context.py +0 -0
  78. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/decorators/utils/__init__.py +0 -0
  79. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/di.py +0 -0
  80. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/imports.py +0 -0
  81. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/logging.py +0 -0
  82. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/monitoring/__init__.py +0 -0
  83. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/monitoring/pool_monitor.py +0 -0
  84. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/monitoring/protocols.py +0 -0
  85. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/py.typed +0 -0
  86. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/reliability/error_classification.py +0 -0
  87. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/reliability/load_control.py +0 -0
  88. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/reliability/metrics_collection.py +0 -0
  89. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/serializers/base.py +0 -0
  90. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/serializers/interop_serializer.py +0 -0
  91. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/serializers/orjson_serializer.py +0 -0
  92. {cachekit-0.20.0 → cachekit-0.22.0}/src/cachekit/serializers/standard_serializer.py +0 -0
@@ -85,6 +85,15 @@ dependencies = [
85
85
  "equator",
86
86
  ]
87
87
 
88
+ [[package]]
89
+ name = "alloca"
90
+ version = "0.4.0"
91
+ source = "registry+https://github.com/rust-lang/crates.io-index"
92
+ checksum = "e5a7d05ea6aea7e9e64d25b9156ba2fee3fdd659e34e41063cd2fc7cd020d7f4"
93
+ dependencies = [
94
+ "cc",
95
+ ]
96
+
88
97
  [[package]]
89
98
  name = "anes"
90
99
  version = "0.1.6"
@@ -127,7 +136,7 @@ version = "1.1.5"
127
136
  source = "registry+https://github.com/rust-lang/crates.io-index"
128
137
  checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
129
138
  dependencies = [
130
- "windows-sys 0.61.2",
139
+ "windows-sys 0.60.2",
131
140
  ]
132
141
 
133
142
  [[package]]
@@ -138,7 +147,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
138
147
  dependencies = [
139
148
  "anstyle",
140
149
  "once_cell_polyfill",
141
- "windows-sys 0.61.2",
150
+ "windows-sys 0.60.2",
142
151
  ]
143
152
 
144
153
  [[package]]
@@ -271,10 +280,10 @@ dependencies = [
271
280
 
272
281
  [[package]]
273
282
  name = "cachekit-rs"
274
- version = "0.20.0"
283
+ version = "0.22.0"
275
284
  dependencies = [
276
285
  "cachekit-core",
277
- "criterion",
286
+ "criterion 0.8.2",
278
287
  "ctor",
279
288
  "divan",
280
289
  "fastrand",
@@ -431,9 +440,9 @@ dependencies = [
431
440
  "cast",
432
441
  "ciborium",
433
442
  "clap",
434
- "criterion-plot",
443
+ "criterion-plot 0.5.0",
435
444
  "is-terminal",
436
- "itertools",
445
+ "itertools 0.10.5",
437
446
  "num-traits",
438
447
  "once_cell",
439
448
  "oorandom",
@@ -447,6 +456,31 @@ dependencies = [
447
456
  "walkdir",
448
457
  ]
449
458
 
459
+ [[package]]
460
+ name = "criterion"
461
+ version = "0.8.2"
462
+ source = "registry+https://github.com/rust-lang/crates.io-index"
463
+ checksum = "950046b2aa2492f9a536f5f4f9a3de7b9e2476e575e05bd6c333371add4d98f3"
464
+ dependencies = [
465
+ "alloca",
466
+ "anes",
467
+ "cast",
468
+ "ciborium",
469
+ "clap",
470
+ "criterion-plot 0.8.2",
471
+ "itertools 0.13.0",
472
+ "num-traits",
473
+ "oorandom",
474
+ "page_size",
475
+ "plotters",
476
+ "rayon",
477
+ "regex",
478
+ "serde",
479
+ "serde_json",
480
+ "tinytemplate",
481
+ "walkdir",
482
+ ]
483
+
450
484
  [[package]]
451
485
  name = "criterion-plot"
452
486
  version = "0.5.0"
@@ -454,7 +488,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
454
488
  checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1"
455
489
  dependencies = [
456
490
  "cast",
457
- "itertools",
491
+ "itertools 0.10.5",
492
+ ]
493
+
494
+ [[package]]
495
+ name = "criterion-plot"
496
+ version = "0.8.2"
497
+ source = "registry+https://github.com/rust-lang/crates.io-index"
498
+ checksum = "d8d80a2f4f5b554395e47b5d8305bc3d27813bacb73493eb1001e8f76dae29ea"
499
+ dependencies = [
500
+ "cast",
501
+ "itertools 0.13.0",
458
502
  ]
459
503
 
460
504
  [[package]]
@@ -501,20 +545,14 @@ dependencies = [
501
545
 
502
546
  [[package]]
503
547
  name = "ctor"
504
- version = "0.4.3"
548
+ version = "0.13.1"
505
549
  source = "registry+https://github.com/rust-lang/crates.io-index"
506
- checksum = "ec09e802f5081de6157da9a75701d6c713d8dc3ba52571fd4bd25f412644e8a6"
550
+ checksum = "3429e8f8e3ce0ffe475c411850f70468c70d7a87d2ac3d15dd44703fb885aede"
507
551
  dependencies = [
508
- "ctor-proc-macro",
509
- "dtor",
552
+ "link-section",
553
+ "linktime-proc-macro",
510
554
  ]
511
555
 
512
- [[package]]
513
- name = "ctor-proc-macro"
514
- version = "0.0.6"
515
- source = "registry+https://github.com/rust-lang/crates.io-index"
516
- checksum = "e2931af7e13dc045d8e9d26afccc6fa115d64e115c9c84b1166288b46f6782c2"
517
-
518
556
  [[package]]
519
557
  name = "ctr"
520
558
  version = "0.9.2"
@@ -590,21 +628,6 @@ dependencies = [
590
628
  "syn",
591
629
  ]
592
630
 
593
- [[package]]
594
- name = "dtor"
595
- version = "0.0.6"
596
- source = "registry+https://github.com/rust-lang/crates.io-index"
597
- checksum = "97cbdf2ad6846025e8e25df05171abfb30e3ababa12ee0a0e44b9bbe570633a8"
598
- dependencies = [
599
- "dtor-proc-macro",
600
- ]
601
-
602
- [[package]]
603
- name = "dtor-proc-macro"
604
- version = "0.0.5"
605
- source = "registry+https://github.com/rust-lang/crates.io-index"
606
- checksum = "7454e41ff9012c00d53cf7f475c5e3afa3b91b7c90568495495e8d9bf47a1055"
607
-
608
631
  [[package]]
609
632
  name = "either"
610
633
  version = "1.15.0"
@@ -644,14 +667,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
644
667
  checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
645
668
  dependencies = [
646
669
  "libc",
647
- "windows-sys 0.61.2",
670
+ "windows-sys 0.52.0",
648
671
  ]
649
672
 
650
673
  [[package]]
651
674
  name = "fastrand"
652
- version = "2.3.0"
675
+ version = "2.5.0"
653
676
  source = "registry+https://github.com/rust-lang/crates.io-index"
654
- checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
677
+ checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223"
655
678
 
656
679
  [[package]]
657
680
  name = "find-msvc-tools"
@@ -786,9 +809,9 @@ dependencies = [
786
809
 
787
810
  [[package]]
788
811
  name = "iai-callgrind"
789
- version = "0.14.2"
812
+ version = "0.16.1"
790
813
  source = "registry+https://github.com/rust-lang/crates.io-index"
791
- checksum = "1c9e864ad001cbbf35a64f7b574998823b8622bb483a25246fa1b0e2b3888686"
814
+ checksum = "0b1e4910d3a9137442723dfb772c32dc10674c4181ca078d2fd227cd5dce9db0"
792
815
  dependencies = [
793
816
  "bincode",
794
817
  "derive_more",
@@ -798,9 +821,9 @@ dependencies = [
798
821
 
799
822
  [[package]]
800
823
  name = "iai-callgrind-macros"
801
- version = "0.5.1"
824
+ version = "0.6.1"
802
825
  source = "registry+https://github.com/rust-lang/crates.io-index"
803
- checksum = "c9cee6c3bc32b63ff40e5e56190b1276d2bd0e0b319aa6f998864c27865d3b4e"
826
+ checksum = "4d03775318d3f9f01b39ac6612b01464006dc397a654a89dd57df2fd34fb68c3"
804
827
  dependencies = [
805
828
  "derive_more",
806
829
  "proc-macro-error2",
@@ -813,9 +836,9 @@ dependencies = [
813
836
 
814
837
  [[package]]
815
838
  name = "iai-callgrind-runner"
816
- version = "0.14.2"
839
+ version = "0.16.1"
817
840
  source = "registry+https://github.com/rust-lang/crates.io-index"
818
- checksum = "a82491521e6505b06a824274712a1307904e7cdfdf047735f7dfdb28b5f7a337"
841
+ checksum = "b74c9743c00c3bca4aaffc69c87cae56837796cd362438daf354a3f785788c68"
819
842
  dependencies = [
820
843
  "serde",
821
844
  ]
@@ -865,7 +888,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46"
865
888
  dependencies = [
866
889
  "hermit-abi",
867
890
  "libc",
868
- "windows-sys 0.61.2",
891
+ "windows-sys 0.52.0",
869
892
  ]
870
893
 
871
894
  [[package]]
@@ -883,6 +906,15 @@ dependencies = [
883
906
  "either",
884
907
  ]
885
908
 
909
+ [[package]]
910
+ name = "itertools"
911
+ version = "0.13.0"
912
+ source = "registry+https://github.com/rust-lang/crates.io-index"
913
+ checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
914
+ dependencies = [
915
+ "either",
916
+ ]
917
+
886
918
  [[package]]
887
919
  name = "itoa"
888
920
  version = "1.0.17"
@@ -911,6 +943,18 @@ version = "0.2.183"
911
943
  source = "registry+https://github.com/rust-lang/crates.io-index"
912
944
  checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d"
913
945
 
946
+ [[package]]
947
+ name = "link-section"
948
+ version = "0.13.1"
949
+ source = "registry+https://github.com/rust-lang/crates.io-index"
950
+ checksum = "ea2c24837c4fd5ab6a31d64133eae954f5199247523cf29586117e85245c0dd3"
951
+
952
+ [[package]]
953
+ name = "linktime-proc-macro"
954
+ version = "0.1.0"
955
+ source = "registry+https://github.com/rust-lang/crates.io-index"
956
+ checksum = "a44cd706ff0d503ee32b2071166510ca27e281228de10cd3aa8d35ff94560f81"
957
+
914
958
  [[package]]
915
959
  name = "linux-raw-sys"
916
960
  version = "0.4.15"
@@ -1034,6 +1078,16 @@ version = "0.3.1"
1034
1078
  source = "registry+https://github.com/rust-lang/crates.io-index"
1035
1079
  checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
1036
1080
 
1081
+ [[package]]
1082
+ name = "page_size"
1083
+ version = "0.6.0"
1084
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1085
+ checksum = "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da"
1086
+ dependencies = [
1087
+ "libc",
1088
+ "winapi",
1089
+ ]
1090
+
1037
1091
  [[package]]
1038
1092
  name = "plotters"
1039
1093
  version = "0.3.7"
@@ -1089,7 +1143,7 @@ dependencies = [
1089
1143
  "aligned-vec",
1090
1144
  "backtrace",
1091
1145
  "cfg-if",
1092
- "criterion",
1146
+ "criterion 0.5.1",
1093
1147
  "findshlibs",
1094
1148
  "inferno",
1095
1149
  "libc",
@@ -1147,9 +1201,9 @@ dependencies = [
1147
1201
 
1148
1202
  [[package]]
1149
1203
  name = "proptest"
1150
- version = "1.10.0"
1204
+ version = "1.11.0"
1151
1205
  source = "registry+https://github.com/rust-lang/crates.io-index"
1152
- checksum = "37566cb3fdacef14c0737f9546df7cfeadbfbc9fef10991038bf5015d0c80532"
1206
+ checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744"
1153
1207
  dependencies = [
1154
1208
  "bit-set",
1155
1209
  "bit-vec",
@@ -1484,7 +1538,7 @@ dependencies = [
1484
1538
  "errno",
1485
1539
  "libc",
1486
1540
  "linux-raw-sys 0.12.1",
1487
- "windows-sys 0.61.2",
1541
+ "windows-sys 0.52.0",
1488
1542
  ]
1489
1543
 
1490
1544
  [[package]]
@@ -1694,7 +1748,7 @@ dependencies = [
1694
1748
  "getrandom 0.3.4",
1695
1749
  "once_cell",
1696
1750
  "rustix 1.1.4",
1697
- "windows-sys 0.61.2",
1751
+ "windows-sys 0.52.0",
1698
1752
  ]
1699
1753
 
1700
1754
  [[package]]
@@ -1981,7 +2035,7 @@ version = "0.1.11"
1981
2035
  source = "registry+https://github.com/rust-lang/crates.io-index"
1982
2036
  checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
1983
2037
  dependencies = [
1984
- "windows-sys 0.61.2",
2038
+ "windows-sys 0.52.0",
1985
2039
  ]
1986
2040
 
1987
2041
  [[package]]
@@ -2201,18 +2255,18 @@ dependencies = [
2201
2255
 
2202
2256
  [[package]]
2203
2257
  name = "zeroize"
2204
- version = "1.8.2"
2258
+ version = "1.9.0"
2205
2259
  source = "registry+https://github.com/rust-lang/crates.io-index"
2206
- checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
2260
+ checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e"
2207
2261
  dependencies = [
2208
2262
  "zeroize_derive",
2209
2263
  ]
2210
2264
 
2211
2265
  [[package]]
2212
2266
  name = "zeroize_derive"
2213
- version = "1.4.3"
2267
+ version = "1.5.0"
2214
2268
  source = "registry+https://github.com/rust-lang/crates.io-index"
2215
- checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e"
2269
+ checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328"
2216
2270
  dependencies = [
2217
2271
  "proc-macro2",
2218
2272
  "quote",
@@ -8,11 +8,11 @@ pyo3 = { version = "0.29", features = ["extension-module"] }
8
8
  serde = { version = "1.0", features = ["derive"] }
9
9
  serde_json = "1.0"
10
10
  bincode = "1.3"
11
- numpy = "0.25"
11
+ numpy = "0.29"
12
12
 
13
13
  # Performance dependencies
14
14
  rayon = "1.8"
15
- simd-json = "0.13"
15
+ simd-json = "0.18"
16
16
  lz4 = "1.24"
17
17
  memmap2 = "0.9"
18
18
 
@@ -41,22 +41,3 @@ opt-level = 1
41
41
  opt-level = 3
42
42
  debug = true
43
43
  lto = "fat"
44
-
45
- # Profile-Guided Optimization - Generate profile data
46
- [profile.release-pgo-generate]
47
- inherits = "release"
48
- # PGO instrumentation adds overhead, disable some optimizations
49
- lto = false
50
- # Keep debug info for profiling
51
- debug = true
52
-
53
- # Profile-Guided Optimization - Use profile data
54
- [profile.release-pgo-use]
55
- inherits = "release"
56
- # Full LTO with profile data for maximum optimization
57
- lto = "fat"
58
- # Strip symbols for smaller binary
59
- strip = true
60
- # Maximum optimization with profile data
61
- opt-level = 3
62
- codegen-units = 1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cachekit
3
- Version: 0.20.0
3
+ Version: 0.22.0
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -20,17 +20,15 @@ Classifier: Topic :: System :: Monitoring
20
20
  Classifier: Topic :: Security :: Cryptography
21
21
  Classifier: Framework :: AsyncIO
22
22
  Classifier: Typing :: Typed
23
- Requires-Dist: redis[hiredis]>=4.0.0
23
+ Requires-Dist: redis[hiredis]>=4.6.0
24
24
  Requires-Dist: pydantic>=2.0.0
25
- Requires-Dist: pydantic-settings>=2.7.0
25
+ Requires-Dist: pydantic-settings>=2.13.0
26
26
  Requires-Dist: prometheus-client>=0.22.1
27
27
  Requires-Dist: psutil>=7.0.0
28
28
  Requires-Dist: blake3>=1.0.5
29
29
  Requires-Dist: msgpack>=1.2.1
30
30
  Requires-Dist: xxhash>=3.5.0
31
- Requires-Dist: httpx[http2]>=0.28.1
32
- Requires-Dist: anyio>=4.14.2
33
- Requires-Dist: h2>=4.4.1
31
+ Requires-Dist: urllib3>=2.8.0
34
32
  Requires-Dist: numpy>=2.0.2 ; extra == 'data'
35
33
  Requires-Dist: pandas>=1.3.0 ; extra == 'data'
36
34
  Requires-Dist: pyarrow>=21.0.0 ; extra == 'data'
@@ -214,6 +212,10 @@ def get_user_profile(user_id: int):
214
212
  return db.fetch_user(user_id)
215
213
  ```
216
214
 
215
+ Setting `CACHEKIT_MASTER_KEY` instead of passing `master_key=` means every preset except
216
+ `@cache.secure` and `@cache.local` must state its intent (`encryption=False` for plaintext), or it raises
217
+ `ConfigurationError` at decoration: the key is a key source, never an on switch.
218
+
217
219
  | Feature | `@cache.minimal` | `@cache.dev` | `@cache.test` | `@cache.production` | `@cache.secure` |
218
220
  |:--------|:----------------:|:------------:|:-------------:|:-------------------:|:---------------:|
219
221
  | Default TTL | 300 s | 300 s | 300 s | 600 s | 600 s |
@@ -222,16 +224,19 @@ def get_user_profile(user_id: int):
222
224
  | Integrity Checking | - | ✅ | - | ✅ | ✅ 🔒 |
223
225
  | Encryption | - | - | - | - | ✅ Required |
224
226
  | L1 SWR (L1-only mode) | - | ✅ | - | ✅ | - |
225
- | L1 Invalidation | - | - | - | ✅ | ✅ |
226
- | Prometheus Metrics | - | - | - | ✅ | ✅ |
227
+ | Prometheus Metrics | - | -¹ | - | ✅ | ✅ |
227
228
  | Tracing | - | ✅ | - | ✅ | ✅ |
228
229
  | Structured Logging | - | ✅ | - | ✅ | ✅ |
229
230
  | **Use Case** | High throughput | Local debugging | Deterministic tests | Production reliability | Compliance/security |
230
231
 
232
+ > ¹ `@cache.dev` exports no Prometheus metrics except `circuit_breaker_state`, which is recorded for every function whose circuit breaker is enabled.
233
+ >
231
234
  > 🔒 `@cache.secure` forces `integrity_checking=True` — passing `integrity_checking=False` raises `ConfigurationError` at decoration, including as an override next to `config=DecoratorConfig.secure(...)`. `@cache.secure` also rejects `config=`; the RORO form is `@cache(config=DecoratorConfig.secure(...))`.
232
235
  >
233
236
  > **Default TTL** follows the cross-SDK [intent-preset spec](https://github.com/cachekit-io/protocol/blob/main/spec/intent-presets.md#default-ttl) (`@cache.io` 3600 s) — the same numbers as cachekit-rs and cachekit-ts. `ttl=` overrides it; `ttl=None` is the explicit never-expire opt-in ([details](docs/configuration.md#intent-presets)).
234
237
  >
238
+ > **Cross-process L1 eviction** is not a preset feature: every preset's `invalidate_cache()` deletes from L1 and L2 alike, and evicting other processes' L1 copies is one process-wide opt-in, `CACHEKIT_INVALIDATION_LISTENER_ENABLED` ([L1 invalidation](docs/features/l1-invalidation.md#cross-process-l1-eviction)).
239
+ >
235
240
  > **L1 SWR** (within-TTL background refresh) runs only in L1-only mode (`backend=None`) — with a backend configured it has no effect. `@cache.io` additionally ships past-TTL SWR via `stale_ttl` ([docs](docs/configuration.md#stale-while-revalidate-stale_ttl)).
236
241
  >
237
242
  > **`@cache.io()`** mirrors `@cache.production` (full reliability + observability) but routes to the managed CachekitIO SaaS backend instead of Redis. **`@cache.local()`** is a separate in-process path backed by `ObjectCache` (raw object references, entry-count LRU, no serialization) — the reliability and encryption features listed above do not apply to it.
@@ -242,7 +247,7 @@ def get_user_profile(user_id: int):
242
247
  See the comparison table above for the exact feature set of each preset.
243
248
 
244
249
  ```python
245
- # Development: verbose logging, integrity checks on, Prometheus off
250
+ # Development: verbose logging, integrity checks on, Prometheus off except circuit_breaker_state
246
251
  @cache.dev
247
252
  def debug_expensive_call():
248
253
  return complex_computation()
@@ -292,6 +297,7 @@ def test_cached_function():
292
297
 
293
298
  - Circuit breaker with graceful degradation
294
299
  - Connection pooling with thread affinity (+28% throughput)
300
+ - CachekitIO keeps idle connections pooled until the server closes them, with TCP keepalive probes, so a request after a pause skips a new TLS handshake
295
301
  - Distributed locking prevents cache stampedes
296
302
  - Pluggable backend abstraction (Redis, CachekitIO, File, Memcached, custom)
297
303
  - Untrusted-decode bounds: nesting depth and header-declared allocation are capped on every cache read (a forged entry is a bounded cache miss), verified against the protocol's shared [`decode-bounds.json`](https://github.com/cachekit-io/protocol/blob/2736a81f2f853cf08c5563c0fe7c8361331fa3ad/test-vectors/decode-bounds.json) vectors
@@ -306,7 +312,7 @@ def test_cached_function():
306
312
  | **StandardSerializer** | ★★★★☆ | General Python types, NumPy, Pandas |
307
313
  | **OrjsonSerializer** | ★★★★★ | JSON APIs (2-5x faster than stdlib) — requires `cachekit[json]` |
308
314
  | **ArrowSerializer** | ★★★★★ | Large DataFrames (6-23x faster for 10K+ rows) |
309
- | **EncryptionWrapper** | ★★★★☆ | Wraps any serializer with AES-256-GCM |
315
+ | **+ Encryption** | ★★★★☆ | Any serializer above, AES-256-GCM encrypted: `@cache.secure(master_key=..., serializer=...)` |
310
316
 
311
317
  <details>
312
318
  <summary><strong>Serializer Examples</strong></summary>
@@ -445,7 +451,9 @@ free-threaded 3.14 with the GIL verified disabled (CI job
445
451
  `test-freethreaded`), and the Rust extension declares free-threaded safety
446
452
  (`gil_used = false`). Free-threaded wheels are **not yet published** and
447
453
  free-threaded builds are not officially supported — blocked upstream on
448
- orjson (no free-threaded wheels) and hiredis (re-enables the GIL on import). See
454
+ orjson (no free-threaded wheels) and hiredis (re-enables the GIL on import;
455
+ cachekit loads redis-py only for its Redis backend, and keeps hiredis out there,
456
+ so redis-py uses its pure-Python parser). See
449
457
  [measured performance results](docs/free-threading.md#measured-performance) and the
450
458
  full concurrency audit: [docs/free-threading.md](docs/free-threading.md).
451
459
 
@@ -496,7 +504,7 @@ info = expensive_func.cache_info()
496
504
  | [Prometheus Metrics][prometheus-url] | Built-in observability |
497
505
  | [Zero-Knowledge Encryption][encryption-url] | Client-side security |
498
506
  | [Interop Mode][interop-url] | Cross-SDK cache sharing with cachekit-ts/rs |
499
- | [L1 Invalidation & SWR][l1-invalidation-url] | Invalidation scope (incl. cross-process whole-function on tenant-scoped Redis from the environment or `RedisBackendProvider`), stale-while-revalidate |
507
+ | [L1 Invalidation & SWR][l1-invalidation-url] | Invalidation scope (incl. cross-process whole-function on tenant-scoped Redis from the environment or `RedisBackendProvider`), opt-in cross-process L1 eviction, stale-while-revalidate |
500
508
  | [Reference Caching][reference-caching-url] | `@cache.local()` for non-serializable objects |
501
509
  | [Rust Serialization][rust-serialization-url] | ByteStorage layer: LZ4, xxHash3, AES-256-GCM |
502
510
  | [SSRF Protection][ssrf-url] | URL allowlisting for the CachekitIO backend |
@@ -508,16 +516,22 @@ info = expensive_func.cache_info()
508
516
  ### Environment Variables
509
517
 
510
518
  ```bash
519
+ # Backend selection: set exactly ONE of CACHEKIT_REDIS_URL, CACHEKIT_API_KEY,
520
+ # CACHEKIT_MEMCACHED_SERVERS, CACHEKIT_FILE_CACHE_DIR. Two or more is a ConfigurationError at
521
+ # first call, and decorators relying on env auto-detection run uncached (docs/backends/README.md).
522
+ # REDIS_URL is only a fallback and never conflicts.
523
+
511
524
  # Redis Connection (priority: CACHEKIT_REDIS_URL > REDIS_URL)
512
525
  CACHEKIT_REDIS_URL="redis://localhost:6379" # Primary (preferred)
513
526
  REDIS_URL="redis://localhost:6379" # Fallback
514
527
 
515
528
  # CachekitIO SaaS Backend (closed beta — request access at cachekit.io)
516
- CACHEKIT_API_KEY="your-api-key" # For @cache.io() — or pass api_key= directly # pragma: allowlist secret
529
+ # For @cache.io() next to Redis, pass api_key= from your secret store instead.
530
+ # CACHEKIT_API_KEY="your-api-key" # pragma: allowlist secret
517
531
  CACHEKIT_API_URL="https://api.cachekit.io" # Default SaaS endpoint
518
532
 
519
533
  # Memcached Backend (optional: pip install cachekit[memcached])
520
- CACHEKIT_MEMCACHED_SERVERS='["mc1:11211", "mc2:11211"]' # Default: 127.0.0.1:11211
534
+ # CACHEKIT_MEMCACHED_SERVERS='["mc1:11211", "mc2:11211"]' # Default: 127.0.0.1:11211
521
535
  CACHEKIT_MEMCACHED_CONNECT_TIMEOUT=2.0 # Default: 2.0 seconds
522
536
  CACHEKIT_MEMCACHED_TIMEOUT=1.0 # Default: 1.0 seconds
523
537
  CACHEKIT_MEMCACHED_KEY_PREFIX="myapp:" # Default: "" (none)
@@ -527,9 +541,6 @@ CACHEKIT_MAX_VALUE_SIZE=104857600
527
541
  CACHEKIT_ARROW_COMPRESSION=zstd
528
542
  ```
529
543
 
530
- > [!NOTE]
531
- > If both `CACHEKIT_REDIS_URL` and `REDIS_URL` are set, `CACHEKIT_REDIS_URL` takes precedence.
532
-
533
544
  ---
534
545
 
535
546
  ## Development
@@ -158,6 +158,10 @@ def get_user_profile(user_id: int):
158
158
  return db.fetch_user(user_id)
159
159
  ```
160
160
 
161
+ Setting `CACHEKIT_MASTER_KEY` instead of passing `master_key=` means every preset except
162
+ `@cache.secure` and `@cache.local` must state its intent (`encryption=False` for plaintext), or it raises
163
+ `ConfigurationError` at decoration: the key is a key source, never an on switch.
164
+
161
165
  | Feature | `@cache.minimal` | `@cache.dev` | `@cache.test` | `@cache.production` | `@cache.secure` |
162
166
  |:--------|:----------------:|:------------:|:-------------:|:-------------------:|:---------------:|
163
167
  | Default TTL | 300 s | 300 s | 300 s | 600 s | 600 s |
@@ -166,16 +170,19 @@ def get_user_profile(user_id: int):
166
170
  | Integrity Checking | - | ✅ | - | ✅ | ✅ 🔒 |
167
171
  | Encryption | - | - | - | - | ✅ Required |
168
172
  | L1 SWR (L1-only mode) | - | ✅ | - | ✅ | - |
169
- | L1 Invalidation | - | - | - | ✅ | ✅ |
170
- | Prometheus Metrics | - | - | - | ✅ | ✅ |
173
+ | Prometheus Metrics | - | -¹ | - | ✅ | ✅ |
171
174
  | Tracing | - | ✅ | - | ✅ | ✅ |
172
175
  | Structured Logging | - | ✅ | - | ✅ | ✅ |
173
176
  | **Use Case** | High throughput | Local debugging | Deterministic tests | Production reliability | Compliance/security |
174
177
 
178
+ > ¹ `@cache.dev` exports no Prometheus metrics except `circuit_breaker_state`, which is recorded for every function whose circuit breaker is enabled.
179
+ >
175
180
  > 🔒 `@cache.secure` forces `integrity_checking=True` — passing `integrity_checking=False` raises `ConfigurationError` at decoration, including as an override next to `config=DecoratorConfig.secure(...)`. `@cache.secure` also rejects `config=`; the RORO form is `@cache(config=DecoratorConfig.secure(...))`.
176
181
  >
177
182
  > **Default TTL** follows the cross-SDK [intent-preset spec](https://github.com/cachekit-io/protocol/blob/main/spec/intent-presets.md#default-ttl) (`@cache.io` 3600 s) — the same numbers as cachekit-rs and cachekit-ts. `ttl=` overrides it; `ttl=None` is the explicit never-expire opt-in ([details](docs/configuration.md#intent-presets)).
178
183
  >
184
+ > **Cross-process L1 eviction** is not a preset feature: every preset's `invalidate_cache()` deletes from L1 and L2 alike, and evicting other processes' L1 copies is one process-wide opt-in, `CACHEKIT_INVALIDATION_LISTENER_ENABLED` ([L1 invalidation](docs/features/l1-invalidation.md#cross-process-l1-eviction)).
185
+ >
179
186
  > **L1 SWR** (within-TTL background refresh) runs only in L1-only mode (`backend=None`) — with a backend configured it has no effect. `@cache.io` additionally ships past-TTL SWR via `stale_ttl` ([docs](docs/configuration.md#stale-while-revalidate-stale_ttl)).
180
187
  >
181
188
  > **`@cache.io()`** mirrors `@cache.production` (full reliability + observability) but routes to the managed CachekitIO SaaS backend instead of Redis. **`@cache.local()`** is a separate in-process path backed by `ObjectCache` (raw object references, entry-count LRU, no serialization) — the reliability and encryption features listed above do not apply to it.
@@ -186,7 +193,7 @@ def get_user_profile(user_id: int):
186
193
  See the comparison table above for the exact feature set of each preset.
187
194
 
188
195
  ```python
189
- # Development: verbose logging, integrity checks on, Prometheus off
196
+ # Development: verbose logging, integrity checks on, Prometheus off except circuit_breaker_state
190
197
  @cache.dev
191
198
  def debug_expensive_call():
192
199
  return complex_computation()
@@ -236,6 +243,7 @@ def test_cached_function():
236
243
 
237
244
  - Circuit breaker with graceful degradation
238
245
  - Connection pooling with thread affinity (+28% throughput)
246
+ - CachekitIO keeps idle connections pooled until the server closes them, with TCP keepalive probes, so a request after a pause skips a new TLS handshake
239
247
  - Distributed locking prevents cache stampedes
240
248
  - Pluggable backend abstraction (Redis, CachekitIO, File, Memcached, custom)
241
249
  - Untrusted-decode bounds: nesting depth and header-declared allocation are capped on every cache read (a forged entry is a bounded cache miss), verified against the protocol's shared [`decode-bounds.json`](https://github.com/cachekit-io/protocol/blob/2736a81f2f853cf08c5563c0fe7c8361331fa3ad/test-vectors/decode-bounds.json) vectors
@@ -250,7 +258,7 @@ def test_cached_function():
250
258
  | **StandardSerializer** | ★★★★☆ | General Python types, NumPy, Pandas |
251
259
  | **OrjsonSerializer** | ★★★★★ | JSON APIs (2-5x faster than stdlib) — requires `cachekit[json]` |
252
260
  | **ArrowSerializer** | ★★★★★ | Large DataFrames (6-23x faster for 10K+ rows) |
253
- | **EncryptionWrapper** | ★★★★☆ | Wraps any serializer with AES-256-GCM |
261
+ | **+ Encryption** | ★★★★☆ | Any serializer above, AES-256-GCM encrypted: `@cache.secure(master_key=..., serializer=...)` |
254
262
 
255
263
  <details>
256
264
  <summary><strong>Serializer Examples</strong></summary>
@@ -389,7 +397,9 @@ free-threaded 3.14 with the GIL verified disabled (CI job
389
397
  `test-freethreaded`), and the Rust extension declares free-threaded safety
390
398
  (`gil_used = false`). Free-threaded wheels are **not yet published** and
391
399
  free-threaded builds are not officially supported — blocked upstream on
392
- orjson (no free-threaded wheels) and hiredis (re-enables the GIL on import). See
400
+ orjson (no free-threaded wheels) and hiredis (re-enables the GIL on import;
401
+ cachekit loads redis-py only for its Redis backend, and keeps hiredis out there,
402
+ so redis-py uses its pure-Python parser). See
393
403
  [measured performance results](docs/free-threading.md#measured-performance) and the
394
404
  full concurrency audit: [docs/free-threading.md](docs/free-threading.md).
395
405
 
@@ -440,7 +450,7 @@ info = expensive_func.cache_info()
440
450
  | [Prometheus Metrics][prometheus-url] | Built-in observability |
441
451
  | [Zero-Knowledge Encryption][encryption-url] | Client-side security |
442
452
  | [Interop Mode][interop-url] | Cross-SDK cache sharing with cachekit-ts/rs |
443
- | [L1 Invalidation & SWR][l1-invalidation-url] | Invalidation scope (incl. cross-process whole-function on tenant-scoped Redis from the environment or `RedisBackendProvider`), stale-while-revalidate |
453
+ | [L1 Invalidation & SWR][l1-invalidation-url] | Invalidation scope (incl. cross-process whole-function on tenant-scoped Redis from the environment or `RedisBackendProvider`), opt-in cross-process L1 eviction, stale-while-revalidate |
444
454
  | [Reference Caching][reference-caching-url] | `@cache.local()` for non-serializable objects |
445
455
  | [Rust Serialization][rust-serialization-url] | ByteStorage layer: LZ4, xxHash3, AES-256-GCM |
446
456
  | [SSRF Protection][ssrf-url] | URL allowlisting for the CachekitIO backend |
@@ -452,16 +462,22 @@ info = expensive_func.cache_info()
452
462
  ### Environment Variables
453
463
 
454
464
  ```bash
465
+ # Backend selection: set exactly ONE of CACHEKIT_REDIS_URL, CACHEKIT_API_KEY,
466
+ # CACHEKIT_MEMCACHED_SERVERS, CACHEKIT_FILE_CACHE_DIR. Two or more is a ConfigurationError at
467
+ # first call, and decorators relying on env auto-detection run uncached (docs/backends/README.md).
468
+ # REDIS_URL is only a fallback and never conflicts.
469
+
455
470
  # Redis Connection (priority: CACHEKIT_REDIS_URL > REDIS_URL)
456
471
  CACHEKIT_REDIS_URL="redis://localhost:6379" # Primary (preferred)
457
472
  REDIS_URL="redis://localhost:6379" # Fallback
458
473
 
459
474
  # CachekitIO SaaS Backend (closed beta — request access at cachekit.io)
460
- CACHEKIT_API_KEY="your-api-key" # For @cache.io() — or pass api_key= directly # pragma: allowlist secret
475
+ # For @cache.io() next to Redis, pass api_key= from your secret store instead.
476
+ # CACHEKIT_API_KEY="your-api-key" # pragma: allowlist secret
461
477
  CACHEKIT_API_URL="https://api.cachekit.io" # Default SaaS endpoint
462
478
 
463
479
  # Memcached Backend (optional: pip install cachekit[memcached])
464
- CACHEKIT_MEMCACHED_SERVERS='["mc1:11211", "mc2:11211"]' # Default: 127.0.0.1:11211
480
+ # CACHEKIT_MEMCACHED_SERVERS='["mc1:11211", "mc2:11211"]' # Default: 127.0.0.1:11211
465
481
  CACHEKIT_MEMCACHED_CONNECT_TIMEOUT=2.0 # Default: 2.0 seconds
466
482
  CACHEKIT_MEMCACHED_TIMEOUT=1.0 # Default: 1.0 seconds
467
483
  CACHEKIT_MEMCACHED_KEY_PREFIX="myapp:" # Default: "" (none)
@@ -471,9 +487,6 @@ CACHEKIT_MAX_VALUE_SIZE=104857600
471
487
  CACHEKIT_ARROW_COMPRESSION=zstd
472
488
  ```
473
489
 
474
- > [!NOTE]
475
- > If both `CACHEKIT_REDIS_URL` and `REDIS_URL` are set, `CACHEKIT_REDIS_URL` takes precedence.
476
-
477
490
  ---
478
491
 
479
492
  ## Development