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 +4 -4
- data/CHANGELOG.md +30 -0
- data/Cargo.lock +64 -71
- data/README.md +52 -0
- data/doc/architecture.md +10 -0
- data/ext/kino/Cargo.toml +2 -2
- data/ext/kino/src/control.rs +103 -6
- data/ext/kino/src/env_strings.rs +267 -124
- data/ext/kino/src/lib.rs +11 -0
- data/ext/kino/src/pin.rs +66 -15
- data/ext/kino/src/queue.rs +99 -3
- data/ext/kino/src/registry.rs +142 -1
- data/ext/kino/src/request.rs +2 -2
- data/ext/kino/src/server.rs +220 -4
- data/ext/kino/src/test_support.rs +44 -0
- data/lib/kino/cli.rb +12 -4
- data/lib/kino/configuration.rb +16 -2
- data/lib/kino/monitor.rb +52 -0
- data/lib/kino/pool_scaler.rb +103 -0
- data/lib/kino/quarantine_monitor.rb +5 -37
- data/lib/kino/ractor_supervisor.rb +102 -8
- data/lib/kino/server.rb +64 -85
- data/lib/kino/slot_bank.rb +31 -0
- data/lib/kino/templates/kino.rb.tt +15 -0
- data/lib/kino/threaded_pool.rb +186 -0
- data/lib/kino/version.rb +1 -1
- data/lib/kino.rb +4 -0
- data/lib/rackup/handler/kino.rb +4 -4
- data/sig/kino.rbs +2 -0
- metadata +6 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: af12e808bb72091d62b6b871006b30fe273e49b25fe89d3f24c8fe2e28a8316f
|
|
4
|
+
data.tar.gz: '06492b24294258e8566f43bff2565309361218914079c054dddcfb64a2fff2aa'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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.
|
|
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.
|
|
59
|
+
version = "2.13.2"
|
|
66
60
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
67
|
-
checksum = "
|
|
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.
|
|
77
|
+
version = "1.4.7"
|
|
84
78
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
85
|
-
checksum = "
|
|
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.
|
|
96
|
+
version = "1.0.5"
|
|
103
97
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
104
|
-
checksum = "
|
|
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.
|
|
165
|
+
version = "0.1.13"
|
|
172
166
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
173
|
-
checksum = "
|
|
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.
|
|
353
|
+
version = "0.1.21"
|
|
362
354
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
363
|
-
checksum = "
|
|
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.
|
|
367
|
+
version = "2.14.2"
|
|
376
368
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
377
|
-
checksum = "
|
|
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.
|
|
392
|
+
version = "0.2.37"
|
|
401
393
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
402
|
-
checksum = "
|
|
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.
|
|
408
|
+
version = "0.1.1"
|
|
417
409
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
418
|
-
checksum = "
|
|
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.
|
|
418
|
+
version = "0.2.37"
|
|
426
419
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
427
|
-
checksum = "
|
|
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.
|
|
430
|
+
version = "0.3.105"
|
|
438
431
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
439
|
-
checksum = "
|
|
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.
|
|
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.
|
|
510
|
+
version = "0.18.5"
|
|
518
511
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
519
|
-
checksum = "
|
|
512
|
+
checksum = "ef9ac18847474e638e3702b76c65d4eb93428471a74778ef0f1be711717f89b5"
|
|
520
513
|
dependencies = [
|
|
521
514
|
"hashbrown",
|
|
522
515
|
]
|
|
523
516
|
|
|
524
517
|
[[package]]
|
|
525
518
|
name = "magnus"
|
|
526
|
-
version = "0.
|
|
519
|
+
version = "0.9.0"
|
|
527
520
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
528
|
-
checksum = "
|
|
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.
|
|
531
|
+
version = "0.9.0"
|
|
539
532
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
540
|
-
checksum = "
|
|
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.
|
|
563
|
+
version = "1.2.3"
|
|
571
564
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
572
|
-
checksum = "
|
|
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.
|
|
625
|
+
version = "0.2.8"
|
|
633
626
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
634
|
-
checksum = "
|
|
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.
|
|
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.
|
|
752
|
+
version = "0.23.45"
|
|
760
753
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
761
|
-
checksum = "
|
|
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.
|
|
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.
|
|
858
|
+
version = "1.16.1"
|
|
866
859
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
867
|
-
checksum = "
|
|
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.
|
|
900
|
+
version = "3.0.6"
|
|
908
901
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
909
|
-
checksum = "
|
|
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.
|
|
911
|
+
version = "2.0.21"
|
|
919
912
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
920
|
-
checksum = "
|
|
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.
|
|
920
|
+
version = "2.0.21"
|
|
928
921
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
929
|
-
checksum = "
|
|
922
|
+
checksum = "fe5197923287db20a58125f0bc85c062f7f2c892de97b18c356f9efb14b28524"
|
|
930
923
|
dependencies = [
|
|
931
924
|
"proc-macro2",
|
|
932
925
|
"quote",
|
|
933
|
-
"syn 3.0.
|
|
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.
|
|
952
|
+
"syn 3.0.6",
|
|
960
953
|
]
|
|
961
954
|
|
|
962
955
|
[[package]]
|
|
963
956
|
name = "tokio-rustls"
|
|
964
|
-
version = "0.26.
|
|
957
|
+
version = "0.26.5"
|
|
965
958
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
966
|
-
checksum = "
|
|
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.
|
|
1006
|
+
version = "1.0.26"
|
|
1014
1007
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1015
|
-
checksum = "
|
|
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.
|
|
1048
|
+
version = "0.2.128"
|
|
1056
1049
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1057
|
-
checksum = "
|
|
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.
|
|
1061
|
+
version = "0.2.128"
|
|
1069
1062
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1070
|
-
checksum = "
|
|
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.
|
|
1071
|
+
version = "0.2.128"
|
|
1079
1072
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1080
|
-
checksum = "
|
|
1073
|
+
checksum = "411e4887f0071ef2d2164a9d5fdf2d20efbef78fccd3a78b0c10a1dc5295e48a"
|
|
1081
1074
|
dependencies = [
|
|
1082
1075
|
"bumpalo",
|
|
1083
1076
|
"proc-macro2",
|
|
1084
1077
|
"quote",
|
|
1085
|
-
"syn
|
|
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.
|
|
1084
|
+
version = "0.2.128"
|
|
1092
1085
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1093
|
-
checksum = "
|
|
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.
|
|
1187
|
+
version = "0.8.58"
|
|
1195
1188
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1196
|
-
checksum = "
|
|
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.
|
|
1196
|
+
version = "0.8.58"
|
|
1204
1197
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1205
|
-
checksum = "
|
|
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.
|
|
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.
|
|
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"
|