kino 0.6.0 → 0.7.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 591ec1716d7d8f23c1483ba2db85f517c42da5de78343c938a27d3e00ca1a66a
4
- data.tar.gz: 91a95efe00e8193be3792c4e2b8055f1b45e2b1a4dcb6acaa1a1a4525300f878
3
+ metadata.gz: af12e808bb72091d62b6b871006b30fe273e49b25fe89d3f24c8fe2e28a8316f
4
+ data.tar.gz: '06492b24294258e8566f43bff2565309361218914079c054dddcfb64a2fff2aa'
5
5
  SHA512:
6
- metadata.gz: ed8d00148990ce34bd73308b376f342b011de37ccf39a078a8676183b0689ad1762af4dc038d6baf2b0501cdb8556a5448e37e0f7ab0c8c755d4e719ceca62c6
7
- data.tar.gz: 8305703e2c93bfbe4a00944a4773213f0414459bfdc2e85f963736767a382d85437889d9b216a845df2e314c4d339e0ddd40aebb5b6689b413c16cdf04e4cc87
6
+ metadata.gz: b53cce2e7b4f05d2932b0557070a8c34fafd0828e65f013106c657604a60344ff2012081cec3f6e8f18c0b20f07367a70bd22e22c3c56f963e6c6d60b6d6b922
7
+ data.tar.gz: f0a316fc52fc6f01caf06bf403ea13d6fb5f3447ee9ee11d22e66d44026dddef078fe569d2e19b9bbc7ff3a470aa470b73b115770c03b7dd5a1fa2cdb3d6e095
data/CHANGELOG.md CHANGED
@@ -1,3 +1,33 @@
1
+ ## [0.7.1] - 2026-09-25
2
+
3
+ - Updated Magnus to 0.9 and other dependencies.
4
+ - Kino is now tested against Ruby HEAD (the unreleased next version)
5
+ as well as Ruby 4.0.
6
+ - Fixed a crash on Ruby 4.1 in ractor mode: with Ruby's new
7
+ per-ractor GC, a worker ractor could collect cached env strings and
8
+ large response bodies that other ractors were still using.
9
+
10
+ ## [0.7.0] - 2026-09-08
11
+
12
+ - Experimental elastic worker pool. Set `max_workers` above `workers`
13
+ and the pool grows under load, one worker at a time, then shrinks
14
+ back to `workers` once the extra workers have sat idle for
15
+ `scale_down_after` seconds (default 30). Works in both modes; a
16
+ retiring worker finishes its request first. `stats`, `/stats` and
17
+ `/metrics` gain `max_workers`, `active_workers`, `scale_ups` and
18
+ `scale_downs`, and each `worker_status` row gains `retired`. Leave
19
+ `max_workers` unset and the pool is fixed, as before.
20
+ - Ractor mode warns at boot when `max_workers` (or `workers`) exceeds
21
+ `RUBY_MAX_CPU` (default 8), Ruby's cap on how many ractors run Ruby
22
+ code at once. Set the variable to your worker count to lift it.
23
+ - Ractor-readiness fixes, so external Ractor audits of Kino pass: the
24
+ env string caches root their strings through the lock-free pin slab
25
+ instead of per-value GC registration (unsynchronized across ractors
26
+ in Ruby 4.0, a crash) and no longer call into Ruby while locked (a
27
+ GC-barrier deadlock); the shared rack.errors and rack.input
28
+ singletons must be Ractor-shareable, not just frozen; the Rack
29
+ handler's option table is shareable. Throughput is unchanged.
30
+
1
31
  ## [0.6.0] - 2026-09-01
2
32
 
3
33
  - HTTP/2 support. Kino now speaks HTTP/2 natively, on by default:
data/Cargo.lock CHANGED
@@ -24,12 +24,6 @@ dependencies = [
24
24
  "memchr",
25
25
  ]
26
26
 
27
- [[package]]
28
- name = "allocator-api2"
29
- version = "0.2.21"
30
- source = "registry+https://github.com/rust-lang/crates.io-index"
31
- checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
32
-
33
27
  [[package]]
34
28
  name = "atomic-waker"
35
29
  version = "1.1.2"
@@ -42,7 +36,7 @@ version = "0.72.1"
42
36
  source = "registry+https://github.com/rust-lang/crates.io-index"
43
37
  checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895"
44
38
  dependencies = [
45
- "bitflags 2.13.1",
39
+ "bitflags 2.13.2",
46
40
  "cexpr",
47
41
  "clang-sys",
48
42
  "itertools",
@@ -62,9 +56,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
62
56
 
63
57
  [[package]]
64
58
  name = "bitflags"
65
- version = "2.13.1"
59
+ version = "2.13.2"
66
60
  source = "registry+https://github.com/rust-lang/crates.io-index"
67
- checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
61
+ checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06"
68
62
 
69
63
  [[package]]
70
64
  name = "bumpalo"
@@ -80,9 +74,9 @@ checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04"
80
74
 
81
75
  [[package]]
82
76
  name = "cc"
83
- version = "1.4.4"
77
+ version = "1.4.7"
84
78
  source = "registry+https://github.com/rust-lang/crates.io-index"
85
- checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273"
79
+ checksum = "54413ede23c2daf518f35156dfde027feb2374004d63bd497f983c8db9c0e313"
86
80
  dependencies = [
87
81
  "find-msvc-tools",
88
82
  "shlex 2.0.1",
@@ -99,9 +93,9 @@ dependencies = [
99
93
 
100
94
  [[package]]
101
95
  name = "cfg-if"
102
- version = "1.0.4"
96
+ version = "1.0.5"
103
97
  source = "registry+https://github.com/rust-lang/crates.io-index"
104
- checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
98
+ checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600"
105
99
 
106
100
  [[package]]
107
101
  name = "clang-sys"
@@ -168,9 +162,9 @@ dependencies = [
168
162
 
169
163
  [[package]]
170
164
  name = "find-msvc-tools"
171
- version = "0.1.11"
165
+ version = "0.1.13"
172
166
  source = "registry+https://github.com/rust-lang/crates.io-index"
173
- checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890"
167
+ checksum = "ef25905e51abafe4dcea6c15fec58c57b601cdbd0ee53d22ea1d3016c587d39b"
174
168
 
175
169
  [[package]]
176
170
  name = "flume"
@@ -284,8 +278,6 @@ version = "0.17.1"
284
278
  source = "registry+https://github.com/rust-lang/crates.io-index"
285
279
  checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
286
280
  dependencies = [
287
- "allocator-api2",
288
- "equivalent",
289
281
  "foldhash",
290
282
  ]
291
283
 
@@ -358,9 +350,9 @@ dependencies = [
358
350
 
359
351
  [[package]]
360
352
  name = "hyper-util"
361
- version = "0.1.20"
353
+ version = "0.1.21"
362
354
  source = "registry+https://github.com/rust-lang/crates.io-index"
363
- checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0"
355
+ checksum = "ddc03d96684f9226b8a787cdb71488417b53ab5ea8fdb1dac946cb9431cc8bff"
364
356
  dependencies = [
365
357
  "bytes",
366
358
  "http",
@@ -372,9 +364,9 @@ dependencies = [
372
364
 
373
365
  [[package]]
374
366
  name = "indexmap"
375
- version = "2.14.1"
367
+ version = "2.14.2"
376
368
  source = "registry+https://github.com/rust-lang/crates.io-index"
377
- checksum = "07aa2048142242915a31d35844fb311e0e53fcca590c3a0a40dcf1b841fa09eb"
369
+ checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855"
378
370
  dependencies = [
379
371
  "equivalent",
380
372
  "hashbrown",
@@ -397,9 +389,9 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
397
389
 
398
390
  [[package]]
399
391
  name = "jiff"
400
- version = "0.2.35"
392
+ version = "0.2.37"
401
393
  source = "registry+https://github.com/rust-lang/crates.io-index"
402
- checksum = "668b7183bd07af9a4885f5c35b0cc5c83c4607a913c16b7e17291832910d2dcc"
394
+ checksum = "0ab1baf72f08796de0260609515130699b890ac25f30e610ad894bc5856cafdb"
403
395
  dependencies = [
404
396
  "defmt",
405
397
  "jiff-core",
@@ -413,18 +405,19 @@ dependencies = [
413
405
 
414
406
  [[package]]
415
407
  name = "jiff-core"
416
- version = "0.1.0"
408
+ version = "0.1.1"
417
409
  source = "registry+https://github.com/rust-lang/crates.io-index"
418
- checksum = "7feca88439efe53da3754500c1851dedf3cb36c524dd5cf8225cc0794de95d09"
410
+ checksum = "5e52fe76043ccecc9005d2305ebaadf7d7fc0cc89ca6baa10a94d6bc68c7128c"
419
411
  dependencies = [
420
412
  "defmt",
413
+ "log",
421
414
  ]
422
415
 
423
416
  [[package]]
424
417
  name = "jiff-static"
425
- version = "0.2.35"
418
+ version = "0.2.37"
426
419
  source = "registry+https://github.com/rust-lang/crates.io-index"
427
- checksum = "3a69dcb3a21cfb32ce1cd056169337ca284af0766dd766e7878819b251a49204"
420
+ checksum = "378268a1116ad67ae6228701118ac9f491d78fda38a40a1f1a9e1348de6f7212"
428
421
  dependencies = [
429
422
  "jiff-core",
430
423
  "proc-macro2",
@@ -434,9 +427,9 @@ dependencies = [
434
427
 
435
428
  [[package]]
436
429
  name = "js-sys"
437
- version = "0.3.104"
430
+ version = "0.3.105"
438
431
  source = "registry+https://github.com/rust-lang/crates.io-index"
439
- checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a"
432
+ checksum = "ce57d20d1ea864ce2ac172ab472d409214f4fd359f0b2a2775abdf522e2af99e"
440
433
  dependencies = [
441
434
  "cfg-if",
442
435
  "wasm-bindgen",
@@ -444,7 +437,7 @@ dependencies = [
444
437
 
445
438
  [[package]]
446
439
  name = "kino"
447
- version = "0.6.0"
440
+ version = "0.7.1"
448
441
  dependencies = [
449
442
  "ahash",
450
443
  "bytes",
@@ -514,18 +507,18 @@ checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6"
514
507
 
515
508
  [[package]]
516
509
  name = "lru"
517
- version = "0.18.3"
510
+ version = "0.18.5"
518
511
  source = "registry+https://github.com/rust-lang/crates.io-index"
519
- checksum = "0d317b4b9eb398e6acce275758ec6125535505e7a146fb1a9b8bda2451b0ff4c"
512
+ checksum = "ef9ac18847474e638e3702b76c65d4eb93428471a74778ef0f1be711717f89b5"
520
513
  dependencies = [
521
514
  "hashbrown",
522
515
  ]
523
516
 
524
517
  [[package]]
525
518
  name = "magnus"
526
- version = "0.8.2"
519
+ version = "0.9.0"
527
520
  source = "registry+https://github.com/rust-lang/crates.io-index"
528
- checksum = "3b36a5b126bbe97eb0d02d07acfeb327036c6319fd816139a49824a83b7f9012"
521
+ checksum = "379d50b6eea4ca84074ccd3e551eb9b07f7865194d5b3198325317e9ef78e5e9"
529
522
  dependencies = [
530
523
  "magnus-macros",
531
524
  "rb-sys",
@@ -535,9 +528,9 @@ dependencies = [
535
528
 
536
529
  [[package]]
537
530
  name = "magnus-macros"
538
- version = "0.8.0"
531
+ version = "0.9.0"
539
532
  source = "registry+https://github.com/rust-lang/crates.io-index"
540
- checksum = "47607461fd8e1513cb4f2076c197d8092d921a1ea75bd08af97398f593751892"
533
+ checksum = "4ca70566af98184bb92d4d9853daaf533c1a3418b9570d0547ea44970035f3fe"
541
534
  dependencies = [
542
535
  "proc-macro2",
543
536
  "quote",
@@ -567,9 +560,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
567
560
 
568
561
  [[package]]
569
562
  name = "mio"
570
- version = "1.2.2"
563
+ version = "1.2.3"
571
564
  source = "registry+https://github.com/rust-lang/crates.io-index"
572
- checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427"
565
+ checksum = "4b18443e9c262bfe8fa82f51666e2642c53393f7e5c27b3e1aeab922cff5b9d8"
573
566
  dependencies = [
574
567
  "libc",
575
568
  "wasi",
@@ -629,9 +622,9 @@ checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85"
629
622
 
630
623
  [[package]]
631
624
  name = "portable-atomic-util"
632
- version = "0.2.7"
625
+ version = "0.2.8"
633
626
  source = "registry+https://github.com/rust-lang/crates.io-index"
634
- checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618"
627
+ checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715"
635
628
  dependencies = [
636
629
  "portable-atomic",
637
630
  ]
@@ -702,7 +695,7 @@ version = "0.5.18"
702
695
  source = "registry+https://github.com/rust-lang/crates.io-index"
703
696
  checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
704
697
  dependencies = [
705
- "bitflags 2.13.1",
698
+ "bitflags 2.13.2",
706
699
  ]
707
700
 
708
701
  [[package]]
@@ -756,9 +749,9 @@ checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d"
756
749
 
757
750
  [[package]]
758
751
  name = "rustls"
759
- version = "0.23.43"
752
+ version = "0.23.45"
760
753
  source = "registry+https://github.com/rust-lang/crates.io-index"
761
- checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06"
754
+ checksum = "0d41d731c7d2f962d1ccc364cec258de3c0e93b38c2fb3ba97ac74513048d634"
762
755
  dependencies = [
763
756
  "log",
764
757
  "once_cell",
@@ -833,7 +826,7 @@ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
833
826
  dependencies = [
834
827
  "proc-macro2",
835
828
  "quote",
836
- "syn 3.0.4",
829
+ "syn 3.0.6",
837
830
  ]
838
831
 
839
832
  [[package]]
@@ -862,9 +855,9 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
862
855
 
863
856
  [[package]]
864
857
  name = "smallvec"
865
- version = "1.15.2"
858
+ version = "1.16.1"
866
859
  source = "registry+https://github.com/rust-lang/crates.io-index"
867
- checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90"
860
+ checksum = "ba467056f1b547ed52077911161fc86985becbc60e8e1857c8a144dab0def891"
868
861
 
869
862
  [[package]]
870
863
  name = "socket2"
@@ -904,9 +897,9 @@ dependencies = [
904
897
 
905
898
  [[package]]
906
899
  name = "syn"
907
- version = "3.0.4"
900
+ version = "3.0.6"
908
901
  source = "registry+https://github.com/rust-lang/crates.io-index"
909
- checksum = "e6275cddf4610d1775e6d1fe9469b2e77d0f39fd98fb7450901b821e0c53649f"
902
+ checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee"
910
903
  dependencies = [
911
904
  "proc-macro2",
912
905
  "quote",
@@ -915,22 +908,22 @@ dependencies = [
915
908
 
916
909
  [[package]]
917
910
  name = "thiserror"
918
- version = "2.0.20"
911
+ version = "2.0.21"
919
912
  source = "registry+https://github.com/rust-lang/crates.io-index"
920
- checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f"
913
+ checksum = "09e52cb86a36cede5cb101bf8908837b3e4c6e5e59fe7fd85c23fb56200d189e"
921
914
  dependencies = [
922
915
  "thiserror-impl",
923
916
  ]
924
917
 
925
918
  [[package]]
926
919
  name = "thiserror-impl"
927
- version = "2.0.20"
920
+ version = "2.0.21"
928
921
  source = "registry+https://github.com/rust-lang/crates.io-index"
929
- checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af"
922
+ checksum = "fe5197923287db20a58125f0bc85c062f7f2c892de97b18c356f9efb14b28524"
930
923
  dependencies = [
931
924
  "proc-macro2",
932
925
  "quote",
933
- "syn 3.0.4",
926
+ "syn 3.0.6",
934
927
  ]
935
928
 
936
929
  [[package]]
@@ -956,14 +949,14 @@ checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e"
956
949
  dependencies = [
957
950
  "proc-macro2",
958
951
  "quote",
959
- "syn 3.0.4",
952
+ "syn 3.0.6",
960
953
  ]
961
954
 
962
955
  [[package]]
963
956
  name = "tokio-rustls"
964
- version = "0.26.4"
957
+ version = "0.26.5"
965
958
  source = "registry+https://github.com/rust-lang/crates.io-index"
966
- checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61"
959
+ checksum = "b0c85f2c3ef0b1cd58b36682f4b17aaa995f0e5db534d85692b4903abce21f67"
967
960
  dependencies = [
968
961
  "rustls",
969
962
  "tokio",
@@ -1010,9 +1003,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
1010
1003
 
1011
1004
  [[package]]
1012
1005
  name = "unicode-ident"
1013
- version = "1.0.24"
1006
+ version = "1.0.26"
1014
1007
  source = "registry+https://github.com/rust-lang/crates.io-index"
1015
- checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
1008
+ checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954"
1016
1009
 
1017
1010
  [[package]]
1018
1011
  name = "untrusted"
@@ -1052,9 +1045,9 @@ dependencies = [
1052
1045
 
1053
1046
  [[package]]
1054
1047
  name = "wasm-bindgen"
1055
- version = "0.2.127"
1048
+ version = "0.2.128"
1056
1049
  source = "registry+https://github.com/rust-lang/crates.io-index"
1057
- checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70"
1050
+ checksum = "aecb87a33d3b0c5e3b7aa46336eaf486cffafbd281b195e4c8b80d50df2351bf"
1058
1051
  dependencies = [
1059
1052
  "cfg-if",
1060
1053
  "once_cell",
@@ -1065,9 +1058,9 @@ dependencies = [
1065
1058
 
1066
1059
  [[package]]
1067
1060
  name = "wasm-bindgen-macro"
1068
- version = "0.2.127"
1061
+ version = "0.2.128"
1069
1062
  source = "registry+https://github.com/rust-lang/crates.io-index"
1070
- checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1"
1063
+ checksum = "a690d511e3c1a8b3a55e33511e3c2c00c78415cd23650f32b808627f5696b9ed"
1071
1064
  dependencies = [
1072
1065
  "quote",
1073
1066
  "wasm-bindgen-macro-support",
@@ -1075,22 +1068,22 @@ dependencies = [
1075
1068
 
1076
1069
  [[package]]
1077
1070
  name = "wasm-bindgen-macro-support"
1078
- version = "0.2.127"
1071
+ version = "0.2.128"
1079
1072
  source = "registry+https://github.com/rust-lang/crates.io-index"
1080
- checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284"
1073
+ checksum = "411e4887f0071ef2d2164a9d5fdf2d20efbef78fccd3a78b0c10a1dc5295e48a"
1081
1074
  dependencies = [
1082
1075
  "bumpalo",
1083
1076
  "proc-macro2",
1084
1077
  "quote",
1085
- "syn 2.0.119",
1078
+ "syn 3.0.6",
1086
1079
  "wasm-bindgen-shared",
1087
1080
  ]
1088
1081
 
1089
1082
  [[package]]
1090
1083
  name = "wasm-bindgen-shared"
1091
- version = "0.2.127"
1084
+ version = "0.2.128"
1092
1085
  source = "registry+https://github.com/rust-lang/crates.io-index"
1093
- checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf"
1086
+ checksum = "81941cd78d0c92026c33e5e01312845a4cb1e9af3407f9134b100dd03144103e"
1094
1087
  dependencies = [
1095
1088
  "unicode-ident",
1096
1089
  ]
@@ -1191,18 +1184,18 @@ checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
1191
1184
 
1192
1185
  [[package]]
1193
1186
  name = "zerocopy"
1194
- version = "0.8.56"
1187
+ version = "0.8.58"
1195
1188
  source = "registry+https://github.com/rust-lang/crates.io-index"
1196
- checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb"
1189
+ checksum = "c17e8fafad82b542ff3717217ecdc736231b59e387768c9630123b4ce4d2db44"
1197
1190
  dependencies = [
1198
1191
  "zerocopy-derive",
1199
1192
  ]
1200
1193
 
1201
1194
  [[package]]
1202
1195
  name = "zerocopy-derive"
1203
- version = "0.8.56"
1196
+ version = "0.8.58"
1204
1197
  source = "registry+https://github.com/rust-lang/crates.io-index"
1205
- checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1"
1198
+ checksum = "595f56e044df4f46a0c9a626f65c3d99eb8488f7e8a8baa12dd76326d9710bf2"
1206
1199
  dependencies = [
1207
1200
  "proc-macro2",
1208
1201
  "quote",
data/README.md CHANGED
@@ -259,6 +259,8 @@ server = Kino::Server.new(app,
259
259
  bind: "127.0.0.1", # or "unix:///run/kino.sock" behind a proxy
260
260
  port: 9292, # 0 = ephemeral; read back via server.port
261
261
  workers: Kino.available_parallelism, # ractors (parallelism); the default
262
+ max_workers: nil, # experimental: grow past workers under load (see Elastic pool)
263
+ scale_down_after: 30, # seconds idle before an extra worker retires
262
264
  threads: 1, # per worker; ractor default 1, threaded default 3
263
265
  mode: :auto, # :auto | :ractor | :threaded
264
266
  queue_depth: 1024, # bounded queue; overflow → 503
@@ -418,6 +420,56 @@ Kino fires four lifecycle hooks alongside `on_error`, split by firing context.
418
420
 
419
421
  A raising hook is logged and never kills a worker.
420
422
 
423
+ ## Elastic pool (experimental)
424
+
425
+ Size the pool for the quiet hours and let it grow for the busy ones:
426
+
427
+ ```ruby
428
+ # kino.rb
429
+ workers 4 # always running
430
+ max_workers 16 # reached only under load
431
+ scale_down_after 30 # seconds idle before an extra worker retires
432
+ ```
433
+
434
+ Or `Kino::Server.new(app, workers: 4, max_workers: 16)`. Leave
435
+ `max_workers` unset and the pool is fixed at `workers`, as before.
436
+
437
+ While requests wait in the queue, Kino adds a worker every 100 ms until
438
+ the queue clears or the pool hits `max_workers`. When the load passes,
439
+ workers above `workers` retire one at a time after `scale_down_after`
440
+ seconds idle, each finishing its current request first. Same behavior
441
+ in `:ractor` and `:threaded` mode.
442
+
443
+ **Use it when your app waits**: on databases, upstream services, slow
444
+ clients. With `workers` at your core count, all workers can be blocked
445
+ on I/O while cores sit idle; a higher ceiling puts those cores to work,
446
+ and a ractor starts in microseconds, so the pool follows load closely.
447
+ Pure CPU work gains nothing past the core count. In `:ractor` mode Ruby
448
+ itself runs at most `RUBY_MAX_CPU` ractors' Ruby code at once (default
449
+ 8), and Kino warns at boot when the pool can exceed it. On a bigger box:
450
+
451
+ ```sh
452
+ RUBY_MAX_CPU=16 kino
453
+ ```
454
+
455
+ **Watch it breathe** in `server.stats`, `GET /stats` and `GET /metrics`:
456
+
457
+ ```sh
458
+ $ curl -s localhost:9293/stats | jq '{workers, max_workers, active_workers, scale_ups, scale_downs}'
459
+ {
460
+ "workers": 4,
461
+ "max_workers": 16,
462
+ "active_workers": 9,
463
+ "scale_ups": 12,
464
+ "scale_downs": 7
465
+ }
466
+ ```
467
+
468
+ Prometheus gets `kino_max_workers`, `kino_active_workers`,
469
+ `kino_scale_ups_total` and `kino_scale_downs_total`. `after_worker_boot`
470
+ fires for every worker the pool adds, `on_worker_exit` (with a nil
471
+ cause) for every one it retires.
472
+
421
473
  ## Stuck-worker quarantine
422
474
 
423
475
  `quarantine_timeout: seconds` (or `quarantine_timeout 60` in `kino.rb`)
data/doc/architecture.md CHANGED
@@ -31,6 +31,16 @@ Puma-style two-level: `workers × threads`.
31
31
  - Identical machinery either way: the flume queue is MPMC, a "worker slot"
32
32
  is per-thread, and the worker loop (`lib/kino/worker.rb`) is shared
33
33
  verbatim.
34
+ - Elastic pool (`max_workers`): a scaler thread on the main ractor
35
+ samples queue depth and the per-slot sensors every 100 ms, adds one
36
+ worker per sample while requests wait, and retires the longest-idle
37
+ worker above the floor after `scale_down_after`. Retirement is a
38
+ per-slot flag raised under the slot's lane lock: the lane dispatcher
39
+ skips the slot, the take loop honors the flag at its next idle tick (a
40
+ request already taken finishes first, a lane worker drains its own
41
+ lane), and the slot is reset and reused by the next worker, so the
42
+ slot table never grows with churn. Both pools (the ractor supervisor
43
+ and the threaded pool) expose the same grow/retire/groups seam.
34
44
  - Experimental `lanes true` replaces the one shared queue with a small
35
45
  private queue per worker slot (awake-preferring dispatch, work
36
46
  stealing); see [benchmarks](benchmarks.md#lane-dispatch-experimental-lanes-true).
data/ext/kino/Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "kino"
3
- version = "0.6.0"
3
+ version = "0.7.1"
4
4
  edition = "2021"
5
5
  authors = ["Yaroslav Markin <yaroslav@markin.net>"]
6
6
  license = "MIT"
@@ -12,7 +12,7 @@ crate-type = ["cdylib", "rlib"]
12
12
 
13
13
 
14
14
  [dependencies]
15
- magnus = { version = "0.8.2", features = ["rb-sys"] }
15
+ magnus = { version = "0.9.0", features = ["rb-sys"] }
16
16
  rb-sys = { version = "0.9", features = ["stable-api-compiled-fallback"] }
17
17
  flume = "0.12"
18
18
  parking_lot = "0.12"