tigerbeetle 0.0.40 → 0.17.8
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/LICENSE +0 -25
- data/README.md +670 -80
- data/docs/migration.md +201 -0
- data/sig/tigerbeetle.rbs +271 -0
- data/src/ext/tigerbeetle/extconf.rb +47 -0
- data/src/ext/tigerbeetle/lib/aarch64-linux-gnu.2.27/libtb_client.so +0 -0
- data/src/ext/tigerbeetle/lib/aarch64-linux-musl/libtb_client.so +0 -0
- data/src/ext/tigerbeetle/lib/aarch64-macos/libtb_client.dylib +0 -0
- data/src/ext/tigerbeetle/lib/x86_64-linux-gnu.2.27/libtb_client.so +0 -0
- data/src/ext/tigerbeetle/lib/x86_64-linux-musl/libtb_client.so +0 -0
- data/src/ext/tigerbeetle/lib/x86_64-macos/libtb_client.dylib +0 -0
- data/src/ext/tigerbeetle/lib/x86_64-windows/tb_client.dll +0 -0
- data/src/ext/tigerbeetle/rb_tb_gen.h +458 -0
- data/{ext/tb_client/tigerbeetle/src/clients/rust/assets → src/ext/tigerbeetle}/tb_client.h +18 -16
- data/src/ext/tigerbeetle/tigerbeetle.c +310 -0
- data/src/tigerbeetle/bindings.rb +347 -0
- data/src/tigerbeetle/client.rb +129 -0
- data/src/tigerbeetle/completion_dispatcher.rb +108 -0
- data/src/tigerbeetle/id.rb +40 -0
- data/src/tigerbeetle/tb.rb +3 -0
- data/src/tigerbeetle/version.rb +3 -0
- data/src/tigerbeetle.rb +39 -0
- metadata +33 -350
- data/CHANGELOG.md +0 -162
- data/ext/tb_client/extconf.rb +0 -41
- data/ext/tb_client/tigerbeetle/LICENSE +0 -177
- data/ext/tb_client/tigerbeetle/build.zig +0 -2296
- data/ext/tb_client/tigerbeetle/src/aof.zig +0 -1000
- data/ext/tb_client/tigerbeetle/src/build/fetch.zig +0 -112
- data/ext/tb_client/tigerbeetle/src/build_multiversion.zig +0 -808
- data/ext/tb_client/tigerbeetle/src/cdc/amqp/protocol.zig +0 -1283
- data/ext/tb_client/tigerbeetle/src/cdc/amqp/spec.zig +0 -1704
- data/ext/tb_client/tigerbeetle/src/cdc/amqp/types.zig +0 -341
- data/ext/tb_client/tigerbeetle/src/cdc/amqp.zig +0 -1450
- data/ext/tb_client/tigerbeetle/src/cdc/runner.zig +0 -1659
- data/ext/tb_client/tigerbeetle/src/clients/c/samples/main.c +0 -406
- data/ext/tb_client/tigerbeetle/src/clients/c/tb_client/context.zig +0 -1092
- data/ext/tb_client/tigerbeetle/src/clients/c/tb_client/echo_client.zig +0 -286
- data/ext/tb_client/tigerbeetle/src/clients/c/tb_client/packet.zig +0 -158
- data/ext/tb_client/tigerbeetle/src/clients/c/tb_client/signal.zig +0 -229
- data/ext/tb_client/tigerbeetle/src/clients/c/tb_client/signal_fuzz.zig +0 -110
- data/ext/tb_client/tigerbeetle/src/clients/c/tb_client.h +0 -386
- data/ext/tb_client/tigerbeetle/src/clients/c/tb_client.zig +0 -34
- data/ext/tb_client/tigerbeetle/src/clients/c/tb_client_exports.zig +0 -281
- data/ext/tb_client/tigerbeetle/src/clients/c/tb_client_header.zig +0 -312
- data/ext/tb_client/tigerbeetle/src/clients/c/tb_client_header_test.zig +0 -138
- data/ext/tb_client/tigerbeetle/src/clients/c/test.zig +0 -466
- data/ext/tb_client/tigerbeetle/src/clients/docs_samples.zig +0 -157
- data/ext/tb_client/tigerbeetle/src/clients/docs_types.zig +0 -90
- data/ext/tb_client/tigerbeetle/src/clients/dotnet/ci.zig +0 -203
- data/ext/tb_client/tigerbeetle/src/clients/dotnet/docs.zig +0 -79
- data/ext/tb_client/tigerbeetle/src/clients/dotnet/dotnet_bindings.zig +0 -542
- data/ext/tb_client/tigerbeetle/src/clients/go/ci.zig +0 -109
- data/ext/tb_client/tigerbeetle/src/clients/go/docs.zig +0 -86
- data/ext/tb_client/tigerbeetle/src/clients/go/go_bindings.zig +0 -370
- data/ext/tb_client/tigerbeetle/src/clients/go/pkg/native/tb_client.h +0 -386
- data/ext/tb_client/tigerbeetle/src/clients/java/ci.zig +0 -167
- data/ext/tb_client/tigerbeetle/src/clients/java/docs.zig +0 -126
- data/ext/tb_client/tigerbeetle/src/clients/java/java_bindings.zig +0 -996
- data/ext/tb_client/tigerbeetle/src/clients/java/src/client.zig +0 -748
- data/ext/tb_client/tigerbeetle/src/clients/java/src/jni.zig +0 -3238
- data/ext/tb_client/tigerbeetle/src/clients/java/src/jni_tests.zig +0 -1718
- data/ext/tb_client/tigerbeetle/src/clients/java/src/jni_thread_cleaner.zig +0 -190
- data/ext/tb_client/tigerbeetle/src/clients/node/ci.zig +0 -104
- data/ext/tb_client/tigerbeetle/src/clients/node/docs.zig +0 -75
- data/ext/tb_client/tigerbeetle/src/clients/node/node.zig +0 -522
- data/ext/tb_client/tigerbeetle/src/clients/node/node_bindings.zig +0 -267
- data/ext/tb_client/tigerbeetle/src/clients/node/src/c.zig +0 -3
- data/ext/tb_client/tigerbeetle/src/clients/node/src/translate.zig +0 -379
- data/ext/tb_client/tigerbeetle/src/clients/python/ci.zig +0 -131
- data/ext/tb_client/tigerbeetle/src/clients/python/docs.zig +0 -63
- data/ext/tb_client/tigerbeetle/src/clients/python/python_bindings.zig +0 -588
- data/ext/tb_client/tigerbeetle/src/clients/rust/ci.zig +0 -73
- data/ext/tb_client/tigerbeetle/src/clients/rust/docs.zig +0 -106
- data/ext/tb_client/tigerbeetle/src/clients/rust/rust_bindings.zig +0 -305
- data/ext/tb_client/tigerbeetle/src/config.zig +0 -296
- data/ext/tb_client/tigerbeetle/src/constants.zig +0 -790
- data/ext/tb_client/tigerbeetle/src/copyhound.zig +0 -202
- data/ext/tb_client/tigerbeetle/src/counting_allocator.zig +0 -72
- data/ext/tb_client/tigerbeetle/src/direction.zig +0 -120
- data/ext/tb_client/tigerbeetle/src/docs_website/build.zig +0 -158
- data/ext/tb_client/tigerbeetle/src/docs_website/src/content.zig +0 -156
- data/ext/tb_client/tigerbeetle/src/docs_website/src/docs.zig +0 -252
- data/ext/tb_client/tigerbeetle/src/docs_website/src/file_checker.zig +0 -313
- data/ext/tb_client/tigerbeetle/src/docs_website/src/html.zig +0 -87
- data/ext/tb_client/tigerbeetle/src/docs_website/src/page_writer.zig +0 -63
- data/ext/tb_client/tigerbeetle/src/docs_website/src/redirects.zig +0 -47
- data/ext/tb_client/tigerbeetle/src/docs_website/src/search_index_writer.zig +0 -28
- data/ext/tb_client/tigerbeetle/src/docs_website/src/service_worker_writer.zig +0 -61
- data/ext/tb_client/tigerbeetle/src/docs_website/src/single_page_writer.zig +0 -169
- data/ext/tb_client/tigerbeetle/src/docs_website/src/website.zig +0 -46
- data/ext/tb_client/tigerbeetle/src/ewah.zig +0 -445
- data/ext/tb_client/tigerbeetle/src/ewah_benchmark.zig +0 -128
- data/ext/tb_client/tigerbeetle/src/ewah_fuzz.zig +0 -171
- data/ext/tb_client/tigerbeetle/src/fuzz_tests.zig +0 -179
- data/ext/tb_client/tigerbeetle/src/integration_tests.zig +0 -662
- data/ext/tb_client/tigerbeetle/src/io/common.zig +0 -155
- data/ext/tb_client/tigerbeetle/src/io/darwin.zig +0 -1093
- data/ext/tb_client/tigerbeetle/src/io/linux.zig +0 -1880
- data/ext/tb_client/tigerbeetle/src/io/test.zig +0 -1005
- data/ext/tb_client/tigerbeetle/src/io/windows.zig +0 -1598
- data/ext/tb_client/tigerbeetle/src/io.zig +0 -34
- data/ext/tb_client/tigerbeetle/src/iops.zig +0 -134
- data/ext/tb_client/tigerbeetle/src/list.zig +0 -236
- data/ext/tb_client/tigerbeetle/src/lsm/binary_search.zig +0 -848
- data/ext/tb_client/tigerbeetle/src/lsm/binary_search_benchmark.zig +0 -179
- data/ext/tb_client/tigerbeetle/src/lsm/cache_map.zig +0 -424
- data/ext/tb_client/tigerbeetle/src/lsm/cache_map_fuzz.zig +0 -420
- data/ext/tb_client/tigerbeetle/src/lsm/compaction.zig +0 -2114
- data/ext/tb_client/tigerbeetle/src/lsm/composite_key.zig +0 -185
- data/ext/tb_client/tigerbeetle/src/lsm/forest.zig +0 -1146
- data/ext/tb_client/tigerbeetle/src/lsm/forest_fuzz.zig +0 -1102
- data/ext/tb_client/tigerbeetle/src/lsm/forest_table_iterator.zig +0 -200
- data/ext/tb_client/tigerbeetle/src/lsm/groove.zig +0 -1495
- data/ext/tb_client/tigerbeetle/src/lsm/k_way_merge.zig +0 -739
- data/ext/tb_client/tigerbeetle/src/lsm/k_way_merge_benchmark.zig +0 -166
- data/ext/tb_client/tigerbeetle/src/lsm/manifest.zig +0 -754
- data/ext/tb_client/tigerbeetle/src/lsm/manifest_level.zig +0 -1294
- data/ext/tb_client/tigerbeetle/src/lsm/manifest_level_fuzz.zig +0 -510
- data/ext/tb_client/tigerbeetle/src/lsm/manifest_log.zig +0 -1241
- data/ext/tb_client/tigerbeetle/src/lsm/manifest_log_fuzz.zig +0 -628
- data/ext/tb_client/tigerbeetle/src/lsm/node_pool.zig +0 -247
- data/ext/tb_client/tigerbeetle/src/lsm/scan_buffer.zig +0 -116
- data/ext/tb_client/tigerbeetle/src/lsm/scan_builder.zig +0 -543
- data/ext/tb_client/tigerbeetle/src/lsm/scan_fuzz.zig +0 -938
- data/ext/tb_client/tigerbeetle/src/lsm/scan_lookup.zig +0 -293
- data/ext/tb_client/tigerbeetle/src/lsm/scan_merge.zig +0 -359
- data/ext/tb_client/tigerbeetle/src/lsm/scan_range.zig +0 -99
- data/ext/tb_client/tigerbeetle/src/lsm/scan_state.zig +0 -17
- data/ext/tb_client/tigerbeetle/src/lsm/scan_tree.zig +0 -962
- data/ext/tb_client/tigerbeetle/src/lsm/schema.zig +0 -617
- data/ext/tb_client/tigerbeetle/src/lsm/scratch_memory.zig +0 -84
- data/ext/tb_client/tigerbeetle/src/lsm/segmented_array.zig +0 -1500
- data/ext/tb_client/tigerbeetle/src/lsm/segmented_array_benchmark.zig +0 -149
- data/ext/tb_client/tigerbeetle/src/lsm/segmented_array_fuzz.zig +0 -7
- data/ext/tb_client/tigerbeetle/src/lsm/set_associative_cache.zig +0 -865
- data/ext/tb_client/tigerbeetle/src/lsm/table.zig +0 -607
- data/ext/tb_client/tigerbeetle/src/lsm/table_memory.zig +0 -843
- data/ext/tb_client/tigerbeetle/src/lsm/table_value_iterator.zig +0 -90
- data/ext/tb_client/tigerbeetle/src/lsm/timestamp_range.zig +0 -40
- data/ext/tb_client/tigerbeetle/src/lsm/tree.zig +0 -629
- data/ext/tb_client/tigerbeetle/src/lsm/tree_fuzz.zig +0 -933
- data/ext/tb_client/tigerbeetle/src/lsm/zig_zag_merge.zig +0 -534
- data/ext/tb_client/tigerbeetle/src/message_buffer.zig +0 -469
- data/ext/tb_client/tigerbeetle/src/message_bus.zig +0 -1219
- data/ext/tb_client/tigerbeetle/src/message_bus_fuzz.zig +0 -936
- data/ext/tb_client/tigerbeetle/src/message_pool.zig +0 -343
- data/ext/tb_client/tigerbeetle/src/multiversion.zig +0 -2195
- data/ext/tb_client/tigerbeetle/src/queue.zig +0 -390
- data/ext/tb_client/tigerbeetle/src/repl/completion.zig +0 -201
- data/ext/tb_client/tigerbeetle/src/repl/parser.zig +0 -1356
- data/ext/tb_client/tigerbeetle/src/repl/terminal.zig +0 -496
- data/ext/tb_client/tigerbeetle/src/repl.zig +0 -1034
- data/ext/tb_client/tigerbeetle/src/scripts/amqp.zig +0 -973
- data/ext/tb_client/tigerbeetle/src/scripts/cfo.zig +0 -1866
- data/ext/tb_client/tigerbeetle/src/scripts/changelog.zig +0 -304
- data/ext/tb_client/tigerbeetle/src/scripts/ci.zig +0 -227
- data/ext/tb_client/tigerbeetle/src/scripts/client_readmes.zig +0 -658
- data/ext/tb_client/tigerbeetle/src/scripts/devhub.zig +0 -466
- data/ext/tb_client/tigerbeetle/src/scripts/release.zig +0 -1058
- data/ext/tb_client/tigerbeetle/src/scripts.zig +0 -105
- data/ext/tb_client/tigerbeetle/src/shell.zig +0 -1195
- data/ext/tb_client/tigerbeetle/src/stack.zig +0 -260
- data/ext/tb_client/tigerbeetle/src/state_machine/auditor.zig +0 -911
- data/ext/tb_client/tigerbeetle/src/state_machine/workload.zig +0 -2079
- data/ext/tb_client/tigerbeetle/src/state_machine.zig +0 -4872
- data/ext/tb_client/tigerbeetle/src/state_machine_fuzz.zig +0 -288
- data/ext/tb_client/tigerbeetle/src/state_machine_tests.zig +0 -3128
- data/ext/tb_client/tigerbeetle/src/static_allocator.zig +0 -82
- data/ext/tb_client/tigerbeetle/src/stdx/bit_set.zig +0 -157
- data/ext/tb_client/tigerbeetle/src/stdx/bounded_array.zig +0 -292
- data/ext/tb_client/tigerbeetle/src/stdx/debug.zig +0 -65
- data/ext/tb_client/tigerbeetle/src/stdx/flags.zig +0 -1414
- data/ext/tb_client/tigerbeetle/src/stdx/huge_page_allocator.zig +0 -115
- data/ext/tb_client/tigerbeetle/src/stdx/mlock.zig +0 -92
- data/ext/tb_client/tigerbeetle/src/stdx/prng.zig +0 -677
- data/ext/tb_client/tigerbeetle/src/stdx/radix.zig +0 -336
- data/ext/tb_client/tigerbeetle/src/stdx/ring_buffer.zig +0 -511
- data/ext/tb_client/tigerbeetle/src/stdx/sort_test.zig +0 -112
- data/ext/tb_client/tigerbeetle/src/stdx/stdx.zig +0 -1163
- data/ext/tb_client/tigerbeetle/src/stdx/testing/low_level_hash_vectors.zig +0 -142
- data/ext/tb_client/tigerbeetle/src/stdx/testing/snaptest.zig +0 -361
- data/ext/tb_client/tigerbeetle/src/stdx/time_units.zig +0 -275
- data/ext/tb_client/tigerbeetle/src/stdx/unshare.zig +0 -295
- data/ext/tb_client/tigerbeetle/src/stdx/vendored/aegis.zig +0 -436
- data/ext/tb_client/tigerbeetle/src/stdx/windows.zig +0 -48
- data/ext/tb_client/tigerbeetle/src/stdx/zipfian.zig +0 -402
- data/ext/tb_client/tigerbeetle/src/storage.zig +0 -489
- data/ext/tb_client/tigerbeetle/src/storage_fuzz.zig +0 -180
- data/ext/tb_client/tigerbeetle/src/testing/bench.zig +0 -146
- data/ext/tb_client/tigerbeetle/src/testing/cluster/grid_checker.zig +0 -53
- data/ext/tb_client/tigerbeetle/src/testing/cluster/journal_checker.zig +0 -61
- data/ext/tb_client/tigerbeetle/src/testing/cluster/manifest_checker.zig +0 -76
- data/ext/tb_client/tigerbeetle/src/testing/cluster/message_bus.zig +0 -110
- data/ext/tb_client/tigerbeetle/src/testing/cluster/network.zig +0 -412
- data/ext/tb_client/tigerbeetle/src/testing/cluster/state_checker.zig +0 -331
- data/ext/tb_client/tigerbeetle/src/testing/cluster/storage_checker.zig +0 -458
- data/ext/tb_client/tigerbeetle/src/testing/cluster.zig +0 -1198
- data/ext/tb_client/tigerbeetle/src/testing/exhaustigen.zig +0 -128
- data/ext/tb_client/tigerbeetle/src/testing/fixtures.zig +0 -181
- data/ext/tb_client/tigerbeetle/src/testing/fuzz.zig +0 -144
- data/ext/tb_client/tigerbeetle/src/testing/id.zig +0 -97
- data/ext/tb_client/tigerbeetle/src/testing/io.zig +0 -317
- data/ext/tb_client/tigerbeetle/src/testing/marks.zig +0 -126
- data/ext/tb_client/tigerbeetle/src/testing/packet_simulator.zig +0 -533
- data/ext/tb_client/tigerbeetle/src/testing/reply_sequence.zig +0 -154
- data/ext/tb_client/tigerbeetle/src/testing/state_machine.zig +0 -389
- data/ext/tb_client/tigerbeetle/src/testing/storage.zig +0 -1247
- data/ext/tb_client/tigerbeetle/src/testing/table.zig +0 -249
- data/ext/tb_client/tigerbeetle/src/testing/time.zig +0 -98
- data/ext/tb_client/tigerbeetle/src/testing/tmp_tigerbeetle.zig +0 -212
- data/ext/tb_client/tigerbeetle/src/testing/vortex/constants.zig +0 -26
- data/ext/tb_client/tigerbeetle/src/testing/vortex/faulty_network.zig +0 -579
- data/ext/tb_client/tigerbeetle/src/testing/vortex/java_driver/ci.zig +0 -39
- data/ext/tb_client/tigerbeetle/src/testing/vortex/logged_process.zig +0 -214
- data/ext/tb_client/tigerbeetle/src/testing/vortex/rust_driver/ci.zig +0 -34
- data/ext/tb_client/tigerbeetle/src/testing/vortex/supervisor.zig +0 -785
- data/ext/tb_client/tigerbeetle/src/testing/vortex/workload.zig +0 -543
- data/ext/tb_client/tigerbeetle/src/testing/vortex/zig_driver.zig +0 -181
- data/ext/tb_client/tigerbeetle/src/tidy.zig +0 -1449
- data/ext/tb_client/tigerbeetle/src/tigerbeetle/benchmark_driver.zig +0 -227
- data/ext/tb_client/tigerbeetle/src/tigerbeetle/benchmark_load.zig +0 -1069
- data/ext/tb_client/tigerbeetle/src/tigerbeetle/cli.zig +0 -1422
- data/ext/tb_client/tigerbeetle/src/tigerbeetle/inspect.zig +0 -1658
- data/ext/tb_client/tigerbeetle/src/tigerbeetle/inspect_integrity.zig +0 -518
- data/ext/tb_client/tigerbeetle/src/tigerbeetle/libtb_client.zig +0 -36
- data/ext/tb_client/tigerbeetle/src/tigerbeetle/main.zig +0 -646
- data/ext/tb_client/tigerbeetle/src/tigerbeetle.zig +0 -958
- data/ext/tb_client/tigerbeetle/src/time.zig +0 -236
- data/ext/tb_client/tigerbeetle/src/trace/event.zig +0 -745
- data/ext/tb_client/tigerbeetle/src/trace/statsd.zig +0 -462
- data/ext/tb_client/tigerbeetle/src/trace.zig +0 -556
- data/ext/tb_client/tigerbeetle/src/unit_tests.zig +0 -321
- data/ext/tb_client/tigerbeetle/src/vopr.zig +0 -1785
- data/ext/tb_client/tigerbeetle/src/vortex.zig +0 -101
- data/ext/tb_client/tigerbeetle/src/vsr/checkpoint_trailer.zig +0 -473
- data/ext/tb_client/tigerbeetle/src/vsr/checksum.zig +0 -208
- data/ext/tb_client/tigerbeetle/src/vsr/checksum_benchmark.zig +0 -43
- data/ext/tb_client/tigerbeetle/src/vsr/client.zig +0 -768
- data/ext/tb_client/tigerbeetle/src/vsr/client_replies.zig +0 -532
- data/ext/tb_client/tigerbeetle/src/vsr/client_sessions.zig +0 -338
- data/ext/tb_client/tigerbeetle/src/vsr/clock.zig +0 -1019
- data/ext/tb_client/tigerbeetle/src/vsr/fault_detector.zig +0 -279
- data/ext/tb_client/tigerbeetle/src/vsr/free_set.zig +0 -1381
- data/ext/tb_client/tigerbeetle/src/vsr/free_set_fuzz.zig +0 -315
- data/ext/tb_client/tigerbeetle/src/vsr/grid.zig +0 -1460
- data/ext/tb_client/tigerbeetle/src/vsr/grid_blocks_missing.zig +0 -757
- data/ext/tb_client/tigerbeetle/src/vsr/grid_scrubber.zig +0 -797
- data/ext/tb_client/tigerbeetle/src/vsr/journal.zig +0 -2586
- data/ext/tb_client/tigerbeetle/src/vsr/marzullo.zig +0 -308
- data/ext/tb_client/tigerbeetle/src/vsr/message_header.zig +0 -1777
- data/ext/tb_client/tigerbeetle/src/vsr/multi_batch.zig +0 -715
- data/ext/tb_client/tigerbeetle/src/vsr/multi_batch_fuzz.zig +0 -185
- data/ext/tb_client/tigerbeetle/src/vsr/repair_budget.zig +0 -333
- data/ext/tb_client/tigerbeetle/src/vsr/replica.zig +0 -12356
- data/ext/tb_client/tigerbeetle/src/vsr/replica_format.zig +0 -416
- data/ext/tb_client/tigerbeetle/src/vsr/replica_reformat.zig +0 -165
- data/ext/tb_client/tigerbeetle/src/vsr/replica_test.zig +0 -2928
- data/ext/tb_client/tigerbeetle/src/vsr/routing.zig +0 -1075
- data/ext/tb_client/tigerbeetle/src/vsr/superblock.zig +0 -1603
- data/ext/tb_client/tigerbeetle/src/vsr/superblock_fuzz.zig +0 -484
- data/ext/tb_client/tigerbeetle/src/vsr/superblock_quorums.zig +0 -405
- data/ext/tb_client/tigerbeetle/src/vsr/superblock_quorums_fuzz.zig +0 -355
- data/ext/tb_client/tigerbeetle/src/vsr/sync.zig +0 -29
- data/ext/tb_client/tigerbeetle/src/vsr.zig +0 -1727
- data/lib/tb_client/shared_lib.rb +0 -66
- data/lib/tb_client.rb +0 -282
- data/lib/tigerbeetle/account.rb +0 -38
- data/lib/tigerbeetle/account_balance.rb +0 -23
- data/lib/tigerbeetle/account_filter.rb +0 -31
- data/lib/tigerbeetle/atomic_counter.rb +0 -14
- data/lib/tigerbeetle/client.rb +0 -214
- data/lib/tigerbeetle/converters/account.rb +0 -63
- data/lib/tigerbeetle/converters/account_balance.rb +0 -31
- data/lib/tigerbeetle/converters/account_filter.rb +0 -32
- data/lib/tigerbeetle/converters/base.rb +0 -35
- data/lib/tigerbeetle/converters/create_accounts_result.rb +0 -21
- data/lib/tigerbeetle/converters/create_transfers_result.rb +0 -21
- data/lib/tigerbeetle/converters/query_filter.rb +0 -33
- data/lib/tigerbeetle/converters/time.rb +0 -23
- data/lib/tigerbeetle/converters/transfer.rb +0 -64
- data/lib/tigerbeetle/converters/uint_128.rb +0 -24
- data/lib/tigerbeetle/converters.rb +0 -12
- data/lib/tigerbeetle/error.rb +0 -4
- data/lib/tigerbeetle/id.rb +0 -30
- data/lib/tigerbeetle/platforms.rb +0 -9
- data/lib/tigerbeetle/query_filter.rb +0 -31
- data/lib/tigerbeetle/request.rb +0 -7
- data/lib/tigerbeetle/transfer.rb +0 -40
- data/lib/tigerbeetle/version.rb +0 -4
- data/lib/tigerbeetle.rb +0 -13
- data/tigerbeetle.gemspec +0 -60
|
@@ -1,533 +0,0 @@
|
|
|
1
|
-
const std = @import("std");
|
|
2
|
-
const assert = std.debug.assert;
|
|
3
|
-
|
|
4
|
-
const log = std.log.scoped(.packet_simulator);
|
|
5
|
-
const vsr = @import("../vsr.zig");
|
|
6
|
-
const fuzz = @import("./fuzz.zig");
|
|
7
|
-
const stdx = @import("stdx");
|
|
8
|
-
const constants = @import("../constants.zig");
|
|
9
|
-
const Ratio = stdx.PRNG.Ratio;
|
|
10
|
-
const Duration = stdx.Duration;
|
|
11
|
-
const Instant = stdx.Instant;
|
|
12
|
-
|
|
13
|
-
pub const PacketSimulatorOptions = struct {
|
|
14
|
-
node_count: u8,
|
|
15
|
-
client_count: u8,
|
|
16
|
-
seed: u64,
|
|
17
|
-
|
|
18
|
-
recorded_count_max: u8 = 0,
|
|
19
|
-
|
|
20
|
-
/// Mean for the exponential distribution used to calculate forward delay.
|
|
21
|
-
one_way_delay_mean: Duration,
|
|
22
|
-
one_way_delay_min: Duration,
|
|
23
|
-
|
|
24
|
-
packet_loss_probability: Ratio = Ratio.zero(),
|
|
25
|
-
packet_replay_probability: Ratio = Ratio.zero(),
|
|
26
|
-
|
|
27
|
-
/// How the partitions should be generated
|
|
28
|
-
partition_mode: PartitionMode = .none,
|
|
29
|
-
|
|
30
|
-
partition_symmetry: PartitionSymmetry = .symmetric,
|
|
31
|
-
|
|
32
|
-
/// Probability per tick that a partition will occur
|
|
33
|
-
partition_probability: Ratio = Ratio.zero(),
|
|
34
|
-
|
|
35
|
-
/// Probability per tick that a partition will resolve
|
|
36
|
-
unpartition_probability: Ratio = Ratio.zero(),
|
|
37
|
-
|
|
38
|
-
/// Minimum time a partition lasts
|
|
39
|
-
partition_stability: u32 = 0,
|
|
40
|
-
|
|
41
|
-
/// Minimum time the cluster is fully connected until it is partitioned again
|
|
42
|
-
unpartition_stability: u32 = 0,
|
|
43
|
-
|
|
44
|
-
/// The maximum number of in-flight packets a path can have before packets are randomly dropped.
|
|
45
|
-
path_maximum_capacity: u8,
|
|
46
|
-
|
|
47
|
-
/// Mean for the exponential distribution used to calculate how long a path is clogged for.
|
|
48
|
-
path_clog_duration_mean: Duration,
|
|
49
|
-
path_clog_probability: Ratio,
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
pub const Path = struct {
|
|
53
|
-
source: u8,
|
|
54
|
-
target: u8,
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
pub const LinkFilter = std.enums.EnumSet(vsr.Command);
|
|
58
|
-
|
|
59
|
-
/// Determines how the partitions are created. Partitions
|
|
60
|
-
/// are two-way, i.e. if i cannot communicate with j, then
|
|
61
|
-
/// j cannot communicate with i.
|
|
62
|
-
///
|
|
63
|
-
/// Only nodes (replicas or standbys) are partitioned. There will always be exactly two partitions.
|
|
64
|
-
pub const PartitionMode = enum {
|
|
65
|
-
/// Disable automatic partitioning.
|
|
66
|
-
none,
|
|
67
|
-
|
|
68
|
-
/// Draws the size of the partition uniformly at random from (1, n-1).
|
|
69
|
-
/// Replicas are randomly assigned a partition.
|
|
70
|
-
uniform_size,
|
|
71
|
-
|
|
72
|
-
/// Assigns each node to a partition uniformly at random. This biases towards
|
|
73
|
-
/// equal-size partitions.
|
|
74
|
-
uniform_partition,
|
|
75
|
-
|
|
76
|
-
/// Isolates exactly one node.
|
|
77
|
-
isolate_single,
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
pub const PartitionSymmetry = enum { symmetric, asymmetric };
|
|
81
|
-
|
|
82
|
-
pub fn PacketSimulatorType(comptime Packet: type) type {
|
|
83
|
-
return struct {
|
|
84
|
-
const PacketSimulator = @This();
|
|
85
|
-
|
|
86
|
-
const VTable = struct {
|
|
87
|
-
packet_command: *const fn (*PacketSimulator, Packet) vsr.Command,
|
|
88
|
-
packet_clone: *const fn (*PacketSimulator, Packet) Packet,
|
|
89
|
-
packet_deinit: *const fn (*PacketSimulator, Packet) void,
|
|
90
|
-
packet_deliver: *const fn (*PacketSimulator, Packet, Path) void,
|
|
91
|
-
packet_delay: *const fn (*PacketSimulator, Packet, Path) Duration =
|
|
92
|
-
&packet_delay_default,
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
const LinkPacket = struct {
|
|
96
|
-
ready_at: Instant,
|
|
97
|
-
packet: Packet,
|
|
98
|
-
|
|
99
|
-
fn less_than(_: void, a: LinkPacket, b: LinkPacket) std.math.Order {
|
|
100
|
-
return std.math.order(a.ready_at.ns, b.ready_at.ns);
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
pub const LinkDropPacketFn = *const fn (packet: Packet) bool;
|
|
105
|
-
|
|
106
|
-
const Link = struct {
|
|
107
|
-
queue: std.PriorityQueue(LinkPacket, void, LinkPacket.less_than),
|
|
108
|
-
/// Commands in the set are delivered.
|
|
109
|
-
/// Commands not in the set are dropped.
|
|
110
|
-
filter: LinkFilter = LinkFilter.initFull(),
|
|
111
|
-
drop_packet_fn: ?LinkDropPacketFn = null,
|
|
112
|
-
/// Commands in the set are recorded for a later replay.
|
|
113
|
-
record: LinkFilter = .{},
|
|
114
|
-
/// We can arbitrary clog a path until a given moment.
|
|
115
|
-
clogged_till: Instant = .{ .ns = 0 },
|
|
116
|
-
|
|
117
|
-
fn should_drop(link: *const @This(), packet: Packet, command: vsr.Command) bool {
|
|
118
|
-
if (!link.filter.contains(command)) {
|
|
119
|
-
return true;
|
|
120
|
-
}
|
|
121
|
-
if (link.drop_packet_fn) |drop_packet_fn| {
|
|
122
|
-
return drop_packet_fn(packet);
|
|
123
|
-
}
|
|
124
|
-
return false;
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
const RecordedPacket = struct {
|
|
129
|
-
packet: Packet,
|
|
130
|
-
path: Path,
|
|
131
|
-
};
|
|
132
|
-
const Recorded = std.ArrayListUnmanaged(RecordedPacket);
|
|
133
|
-
|
|
134
|
-
options: PacketSimulatorOptions,
|
|
135
|
-
vtable: VTable,
|
|
136
|
-
prng: stdx.PRNG,
|
|
137
|
-
ticks: u64 = 0,
|
|
138
|
-
|
|
139
|
-
/// A send and receive path between each node in the network.
|
|
140
|
-
/// Indexed by path_index().
|
|
141
|
-
links: []Link,
|
|
142
|
-
|
|
143
|
-
/// Recorded messages for manual replay in unit-tests.
|
|
144
|
-
recorded: Recorded,
|
|
145
|
-
|
|
146
|
-
/// Scratch space for automatically generating partitions.
|
|
147
|
-
/// The "source of truth" for partitions is links[*].filter.
|
|
148
|
-
auto_partition: []bool,
|
|
149
|
-
auto_partition_active: bool,
|
|
150
|
-
auto_partition_nodes: []u8,
|
|
151
|
-
auto_partition_stability: u32,
|
|
152
|
-
|
|
153
|
-
pub fn init(
|
|
154
|
-
allocator: std.mem.Allocator,
|
|
155
|
-
options: PacketSimulatorOptions,
|
|
156
|
-
vtable: VTable,
|
|
157
|
-
) !PacketSimulator {
|
|
158
|
-
assert(options.node_count > 0);
|
|
159
|
-
assert(options.one_way_delay_mean.ns >= options.one_way_delay_min.ns);
|
|
160
|
-
|
|
161
|
-
const process_count_ = options.node_count + options.client_count;
|
|
162
|
-
const links = try allocator.alloc(Link, @as(usize, process_count_) * process_count_);
|
|
163
|
-
errdefer allocator.free(links);
|
|
164
|
-
|
|
165
|
-
for (links, 0..) |*link, i| {
|
|
166
|
-
errdefer for (links[0..i]) |*l| l.queue.deinit();
|
|
167
|
-
|
|
168
|
-
link.* = .{
|
|
169
|
-
.queue = std.PriorityQueue(LinkPacket, void, LinkPacket.less_than)
|
|
170
|
-
.init(allocator, {}),
|
|
171
|
-
};
|
|
172
|
-
try link.queue.ensureTotalCapacity(options.path_maximum_capacity);
|
|
173
|
-
}
|
|
174
|
-
errdefer for (links) |*link| link.queue.deinit();
|
|
175
|
-
|
|
176
|
-
var recorded = try Recorded.initCapacity(allocator, options.recorded_count_max);
|
|
177
|
-
errdefer recorded.deinit(allocator);
|
|
178
|
-
|
|
179
|
-
const auto_partition = try allocator.alloc(bool, @as(usize, options.node_count));
|
|
180
|
-
errdefer allocator.free(auto_partition);
|
|
181
|
-
@memset(auto_partition, false);
|
|
182
|
-
|
|
183
|
-
const auto_partition_nodes = try allocator.alloc(u8, @as(usize, options.node_count));
|
|
184
|
-
errdefer allocator.free(auto_partition_nodes);
|
|
185
|
-
for (auto_partition_nodes, 0..) |*node, i| node.* = @intCast(i);
|
|
186
|
-
|
|
187
|
-
return PacketSimulator{
|
|
188
|
-
.options = options,
|
|
189
|
-
.vtable = vtable,
|
|
190
|
-
.prng = stdx.PRNG.from_seed(options.seed),
|
|
191
|
-
.links = links,
|
|
192
|
-
|
|
193
|
-
.recorded = recorded,
|
|
194
|
-
|
|
195
|
-
.auto_partition_active = false,
|
|
196
|
-
.auto_partition = auto_partition,
|
|
197
|
-
.auto_partition_nodes = auto_partition_nodes,
|
|
198
|
-
.auto_partition_stability = options.unpartition_stability,
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
pub fn deinit(self: *PacketSimulator, allocator: std.mem.Allocator) void {
|
|
203
|
-
for (self.links) |*link| {
|
|
204
|
-
for (link.queue.items) |link_packet| {
|
|
205
|
-
self.packet_deinit(link_packet.packet);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
link.queue.deinit();
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
while (self.recorded.pop()) |recorded_packet| {
|
|
212
|
-
self.packet_deinit(recorded_packet.packet);
|
|
213
|
-
}
|
|
214
|
-
self.recorded.deinit(allocator);
|
|
215
|
-
|
|
216
|
-
allocator.free(self.links);
|
|
217
|
-
allocator.free(self.auto_partition);
|
|
218
|
-
allocator.free(self.auto_partition_nodes);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/// Drop all pending packets.
|
|
222
|
-
pub fn link_clear(self: *PacketSimulator, path: Path) void {
|
|
223
|
-
const link = &self.links[self.path_index(path)];
|
|
224
|
-
while (link.queue.removeOrNull()) |link_packet| {
|
|
225
|
-
self.packet_deinit(link_packet.packet);
|
|
226
|
-
}
|
|
227
|
-
assert(link.queue.count() == 0);
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
pub fn link_filter(self: *PacketSimulator, path: Path) *LinkFilter {
|
|
231
|
-
return &self.links[self.path_index(path)].filter;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
pub fn link_drop_packet_fn(self: *PacketSimulator, path: Path) *?LinkDropPacketFn {
|
|
235
|
-
return &self.links[self.path_index(path)].drop_packet_fn;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
pub fn link_record(self: *PacketSimulator, path: Path) *LinkFilter {
|
|
239
|
-
return &self.links[self.path_index(path)].record;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
pub fn replay_recorded(self: *PacketSimulator) void {
|
|
243
|
-
assert(self.recorded.items.len > 0);
|
|
244
|
-
|
|
245
|
-
var recording = false;
|
|
246
|
-
for (self.links) |*link| {
|
|
247
|
-
recording = recording or link.record.bits.count() > 0;
|
|
248
|
-
link.record = .{};
|
|
249
|
-
}
|
|
250
|
-
assert(recording);
|
|
251
|
-
|
|
252
|
-
while (self.recorded.pop()) |packet| {
|
|
253
|
-
self.submit_packet(packet.packet, packet.path);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
fn process_count(self: *const PacketSimulator) usize {
|
|
258
|
-
return self.options.node_count + self.options.client_count;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
fn path_index(self: *const PacketSimulator, path: Path) usize {
|
|
262
|
-
assert(path.source < self.process_count());
|
|
263
|
-
assert(path.target < self.process_count());
|
|
264
|
-
|
|
265
|
-
return @as(usize, path.source) * self.process_count() + path.target;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
fn should_drop(self: *PacketSimulator) bool {
|
|
269
|
-
return self.prng.chance(self.options.packet_loss_probability);
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
fn is_clogged(self: *PacketSimulator, path: Path) bool {
|
|
273
|
-
return self.links[self.path_index(path)].clogged_till.ns > self.tick_instant().ns;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
fn should_clog(self: *PacketSimulator, path: Path) bool {
|
|
277
|
-
_ = path;
|
|
278
|
-
|
|
279
|
-
return self.prng.chance(self.options.path_clog_probability);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
fn clog_for(self: *PacketSimulator, path: Path, duration: Duration) void {
|
|
283
|
-
self.links[self.path_index(path)].clogged_till =
|
|
284
|
-
self.tick_instant().add(duration);
|
|
285
|
-
log.debug("Path path.source={} path.target={} clogged for {}", .{
|
|
286
|
-
path.source,
|
|
287
|
-
path.target,
|
|
288
|
-
duration,
|
|
289
|
-
});
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
fn should_replay(self: *PacketSimulator) bool {
|
|
293
|
-
return self.prng.chance(self.options.packet_replay_probability);
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
fn should_partition(self: *PacketSimulator) bool {
|
|
297
|
-
return self.prng.chance(self.options.partition_probability);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
fn should_unpartition(self: *PacketSimulator) bool {
|
|
301
|
-
return self.prng.chance(self.options.unpartition_probability);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
/// Partitions the network. Guaranteed to isolate at least one replica.
|
|
305
|
-
fn auto_partition_network(self: *PacketSimulator) void {
|
|
306
|
-
assert(self.options.node_count > 1);
|
|
307
|
-
|
|
308
|
-
var partition = self.auto_partition;
|
|
309
|
-
switch (self.options.partition_mode) {
|
|
310
|
-
.none => @memset(partition, false),
|
|
311
|
-
.uniform_size => {
|
|
312
|
-
const partition_size =
|
|
313
|
-
self.prng.range_inclusive(u8, 1, self.options.node_count - 1);
|
|
314
|
-
self.prng.shuffle(u8, self.auto_partition_nodes);
|
|
315
|
-
for (self.auto_partition_nodes, 0..) |r, i| {
|
|
316
|
-
partition[r] = i < partition_size;
|
|
317
|
-
}
|
|
318
|
-
},
|
|
319
|
-
.uniform_partition => {
|
|
320
|
-
var only_same = true;
|
|
321
|
-
partition[0] = self.prng.boolean();
|
|
322
|
-
|
|
323
|
-
var i: usize = 1;
|
|
324
|
-
while (i < self.options.node_count) : (i += 1) {
|
|
325
|
-
partition[i] = self.prng.boolean();
|
|
326
|
-
only_same =
|
|
327
|
-
only_same and (partition[i - 1] == partition[i]);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
if (only_same) {
|
|
331
|
-
const n = self.prng.index(partition);
|
|
332
|
-
partition[n] = true;
|
|
333
|
-
}
|
|
334
|
-
},
|
|
335
|
-
.isolate_single => {
|
|
336
|
-
@memset(partition, false);
|
|
337
|
-
const n = self.prng.index(partition);
|
|
338
|
-
partition[n] = true;
|
|
339
|
-
},
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
self.auto_partition_active = true;
|
|
343
|
-
self.auto_partition_stability = self.options.partition_stability;
|
|
344
|
-
|
|
345
|
-
const asymmetric_partition_side = self.prng.boolean();
|
|
346
|
-
var from: u8 = 0;
|
|
347
|
-
while (from < self.process_count()) : (from += 1) {
|
|
348
|
-
var to: u8 = 0;
|
|
349
|
-
while (to < self.process_count()) : (to += 1) {
|
|
350
|
-
const path: Path = .{ .source = from, .target = to };
|
|
351
|
-
const enabled =
|
|
352
|
-
from >= self.options.node_count or
|
|
353
|
-
to >= self.options.node_count or
|
|
354
|
-
partition[from] == partition[to] or
|
|
355
|
-
(self.options.partition_symmetry == .asymmetric and
|
|
356
|
-
partition[from] == asymmetric_partition_side);
|
|
357
|
-
self.links[self.path_index(path)].filter =
|
|
358
|
-
if (enabled) LinkFilter.initFull() else LinkFilter{};
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
pub fn step(self: *PacketSimulator) bool {
|
|
364
|
-
var advanced = false;
|
|
365
|
-
for (0..self.process_count()) |from| {
|
|
366
|
-
for (0..self.process_count()) |to| {
|
|
367
|
-
const path: Path = .{ .source = @intCast(from), .target = @intCast(to) };
|
|
368
|
-
if (self.is_clogged(path)) continue;
|
|
369
|
-
|
|
370
|
-
const queue = &self.links[self.path_index(path)].queue;
|
|
371
|
-
if (queue.peek()) |link_packet| {
|
|
372
|
-
if (link_packet.ready_at.ns <= self.tick_instant().ns) {
|
|
373
|
-
_ = queue.remove();
|
|
374
|
-
self.submit_packet_finish(path, link_packet);
|
|
375
|
-
self.packet_deinit(link_packet.packet);
|
|
376
|
-
advanced = true;
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
return advanced;
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
pub fn tick(self: *PacketSimulator) void {
|
|
385
|
-
self.ticks += 1;
|
|
386
|
-
|
|
387
|
-
if (self.auto_partition_stability > 0) {
|
|
388
|
-
self.auto_partition_stability -= 1;
|
|
389
|
-
} else {
|
|
390
|
-
if (self.auto_partition_active) {
|
|
391
|
-
if (self.should_unpartition()) {
|
|
392
|
-
self.auto_partition_active = false;
|
|
393
|
-
self.auto_partition_stability = self.options.unpartition_stability;
|
|
394
|
-
@memset(self.auto_partition, false);
|
|
395
|
-
for (self.links) |*link| link.filter = LinkFilter.initFull();
|
|
396
|
-
log.warn("unpartitioned network: partition={any}", .{self.auto_partition});
|
|
397
|
-
}
|
|
398
|
-
} else {
|
|
399
|
-
if (self.options.node_count > 1 and self.should_partition()) {
|
|
400
|
-
self.auto_partition_network();
|
|
401
|
-
log.warn("partitioned network: partition={any}", .{self.auto_partition});
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
for (0..self.process_count()) |from| {
|
|
407
|
-
for (0..self.process_count()) |to| {
|
|
408
|
-
const path: Path = .{ .source = @intCast(from), .target = @intCast(to) };
|
|
409
|
-
if (self.should_clog(path)) {
|
|
410
|
-
self.clog_for(path, .{
|
|
411
|
-
.ns = fuzz.random_int_exponential(
|
|
412
|
-
&self.prng,
|
|
413
|
-
u64,
|
|
414
|
-
self.options.path_clog_duration_mean.ns,
|
|
415
|
-
),
|
|
416
|
-
});
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
pub fn submit_packet(
|
|
423
|
-
self: *PacketSimulator,
|
|
424
|
-
packet: Packet,
|
|
425
|
-
path: Path,
|
|
426
|
-
) void {
|
|
427
|
-
const queue = &self.links[self.path_index(path)].queue;
|
|
428
|
-
const queue_count = queue.count();
|
|
429
|
-
if (queue_count + 1 > self.options.path_maximum_capacity) {
|
|
430
|
-
const link_packet = queue.removeIndex(self.prng.index(queue.items));
|
|
431
|
-
defer self.packet_deinit(link_packet.packet);
|
|
432
|
-
|
|
433
|
-
log.warn("submit_packet: {} reached capacity, dropped packet: {}", .{
|
|
434
|
-
path,
|
|
435
|
-
if (@typeInfo(Packet) == .pointer)
|
|
436
|
-
link_packet.packet.header
|
|
437
|
-
else
|
|
438
|
-
link_packet.packet,
|
|
439
|
-
});
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
queue.add(.{
|
|
443
|
-
.ready_at = self.tick_instant().add(self.packet_delay(packet, path)),
|
|
444
|
-
.packet = packet,
|
|
445
|
-
}) catch unreachable;
|
|
446
|
-
|
|
447
|
-
const command = self.packet_command(packet);
|
|
448
|
-
const recording = self.links[self.path_index(path)].record.contains(command);
|
|
449
|
-
if (recording) {
|
|
450
|
-
self.recorded.addOneAssumeCapacity().* = .{
|
|
451
|
-
.packet = self.packet_clone(packet),
|
|
452
|
-
.path = path,
|
|
453
|
-
};
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
fn submit_packet_finish(self: *PacketSimulator, path: Path, link_packet: LinkPacket) void {
|
|
458
|
-
assert(link_packet.ready_at.ns <= self.tick_instant().ns);
|
|
459
|
-
const command = self.packet_command(link_packet.packet);
|
|
460
|
-
if (self.links[self.path_index(path)].should_drop(link_packet.packet, command)) {
|
|
461
|
-
log.warn(
|
|
462
|
-
"dropped packet (different partitions): from={} to={}: {}",
|
|
463
|
-
.{
|
|
464
|
-
path.source,
|
|
465
|
-
path.target,
|
|
466
|
-
if (@typeInfo(Packet) == .pointer)
|
|
467
|
-
link_packet.packet.header
|
|
468
|
-
else
|
|
469
|
-
link_packet.packet,
|
|
470
|
-
},
|
|
471
|
-
);
|
|
472
|
-
return;
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
if (self.should_drop()) {
|
|
476
|
-
log.warn("dropped packet from={} to={}: {}", .{
|
|
477
|
-
path.source,
|
|
478
|
-
path.target,
|
|
479
|
-
if (@typeInfo(Packet) == .pointer)
|
|
480
|
-
link_packet.packet.header
|
|
481
|
-
else
|
|
482
|
-
link_packet.packet,
|
|
483
|
-
});
|
|
484
|
-
return;
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
if (self.should_replay()) {
|
|
488
|
-
self.submit_packet(
|
|
489
|
-
self.packet_clone(link_packet.packet),
|
|
490
|
-
path,
|
|
491
|
-
);
|
|
492
|
-
log.debug("replayed packet from={} to={}", .{ path.source, path.target });
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
log.debug("delivering packet from={} to={}", .{ path.source, path.target });
|
|
496
|
-
self.packet_deliver(link_packet.packet, path);
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
fn tick_instant(self: *const PacketSimulator) Instant {
|
|
500
|
-
return .{ .ns = self.ticks * constants.tick_ms * std.time.ns_per_ms };
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
fn packet_command(self: *PacketSimulator, packet: Packet) vsr.Command {
|
|
504
|
-
return self.vtable.packet_command(self, packet);
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
fn packet_clone(self: *PacketSimulator, packet: Packet) Packet {
|
|
508
|
-
return self.vtable.packet_clone(self, packet);
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
fn packet_deinit(self: *PacketSimulator, packet: Packet) void {
|
|
512
|
-
self.vtable.packet_deinit(self, packet);
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
fn packet_deliver(self: *PacketSimulator, packet: Packet, path: Path) void {
|
|
516
|
-
self.vtable.packet_deliver(self, packet, path);
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
fn packet_delay(self: *PacketSimulator, packet: Packet, path: Path) Duration {
|
|
520
|
-
return self.vtable.packet_delay(self, packet, path);
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
/// Return a value produced using an exponential distribution with
|
|
524
|
-
/// the minimum and mean specified in self.options
|
|
525
|
-
fn packet_delay_default(self: *PacketSimulator, _: Packet, _: Path) Duration {
|
|
526
|
-
const min = self.options.one_way_delay_min;
|
|
527
|
-
const mean = self.options.one_way_delay_mean;
|
|
528
|
-
return .{
|
|
529
|
-
.ns = @max(min.ns, fuzz.random_int_exponential(&self.prng, u64, mean.ns)),
|
|
530
|
-
};
|
|
531
|
-
}
|
|
532
|
-
};
|
|
533
|
-
}
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
//! Replies from the cluster may arrive out-of-order; the ReplySequence reassembles them in the
|
|
2
|
-
//! correct order (by ascending op number).
|
|
3
|
-
const std = @import("std");
|
|
4
|
-
const assert = std.debug.assert;
|
|
5
|
-
const maybe = stdx.maybe;
|
|
6
|
-
|
|
7
|
-
const stdx = @import("stdx");
|
|
8
|
-
const constants = @import("../constants.zig");
|
|
9
|
-
const MessagePool = @import("../message_pool.zig").MessagePool;
|
|
10
|
-
const Message = MessagePool.Message;
|
|
11
|
-
|
|
12
|
-
const PriorityQueue = std.PriorityQueue;
|
|
13
|
-
|
|
14
|
-
/// Both messages belong to the ReplySequence's `MessagePool`.
|
|
15
|
-
const PendingReply = struct {
|
|
16
|
-
/// `client_index` is null when the prepare does not originate from a client.
|
|
17
|
-
client_index: ?usize,
|
|
18
|
-
prepare: *Message.Prepare,
|
|
19
|
-
reply: *Message.Reply,
|
|
20
|
-
|
|
21
|
-
/// `PendingReply`s are ordered by ascending reply op.
|
|
22
|
-
fn compare(context: void, a: PendingReply, b: PendingReply) std.math.Order {
|
|
23
|
-
_ = context;
|
|
24
|
-
return std.math.order(a.reply.header.op, b.reply.header.op);
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
const PendingReplyQueue = PriorityQueue(PendingReply, void, PendingReply.compare);
|
|
29
|
-
|
|
30
|
-
pub const ReplySequence = struct {
|
|
31
|
-
/// Reply messages (from cluster to client) may be reordered during transit.
|
|
32
|
-
/// The ReplySequence must reassemble them in the original order (ascending op/commit
|
|
33
|
-
/// number) before handing them off to the Workload for verification.
|
|
34
|
-
///
|
|
35
|
-
/// `ReplySequence.stalled_queue` hold replies (and corresponding prepares) that are
|
|
36
|
-
/// waiting to be processed.
|
|
37
|
-
pub const stalled_queue_capacity =
|
|
38
|
-
constants.clients_max * constants.client_request_queue_max * 2;
|
|
39
|
-
|
|
40
|
-
message_pool: MessagePool,
|
|
41
|
-
|
|
42
|
-
/// The list of messages waiting to be verified (the reply for a lower op has not yet arrived).
|
|
43
|
-
/// Includes `register` messages.
|
|
44
|
-
stalled_queue: PendingReplyQueue,
|
|
45
|
-
|
|
46
|
-
pub fn init(allocator: std.mem.Allocator) !ReplySequence {
|
|
47
|
-
// *2 for PendingReply.prepare and PendingReply.reply.
|
|
48
|
-
var message_pool = try MessagePool.init_capacity(allocator, stalled_queue_capacity * 2);
|
|
49
|
-
errdefer message_pool.deinit(allocator);
|
|
50
|
-
|
|
51
|
-
var stalled_queue = PendingReplyQueue.init(allocator, {});
|
|
52
|
-
errdefer stalled_queue.deinit();
|
|
53
|
-
try stalled_queue.ensureTotalCapacity(stalled_queue_capacity);
|
|
54
|
-
|
|
55
|
-
return ReplySequence{
|
|
56
|
-
.message_pool = message_pool,
|
|
57
|
-
.stalled_queue = stalled_queue,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
pub fn deinit(sequence: *ReplySequence, allocator: std.mem.Allocator) void {
|
|
62
|
-
while (sequence.stalled_queue.removeOrNull()) |pending| {
|
|
63
|
-
sequence.message_pool.unref(pending.prepare);
|
|
64
|
-
sequence.message_pool.unref(pending.reply);
|
|
65
|
-
}
|
|
66
|
-
sequence.stalled_queue.deinit();
|
|
67
|
-
sequence.message_pool.deinit(allocator);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
pub fn empty(sequence: *const ReplySequence) bool {
|
|
71
|
-
return sequence.stalled_queue.count() == 0;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
pub fn free(sequence: ReplySequence) usize {
|
|
75
|
-
return stalled_queue_capacity - sequence.stalled_queue.count();
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
pub fn insert(
|
|
79
|
-
sequence: *ReplySequence,
|
|
80
|
-
client_index: ?usize,
|
|
81
|
-
prepare_message: *const Message.Prepare,
|
|
82
|
-
reply_message: *const Message.Reply,
|
|
83
|
-
) void {
|
|
84
|
-
assert(sequence.stalled_queue.count() < stalled_queue_capacity);
|
|
85
|
-
|
|
86
|
-
assert(prepare_message.header.invalid() == null);
|
|
87
|
-
assert(prepare_message.header.command == .prepare);
|
|
88
|
-
|
|
89
|
-
// The ReplySequence includes "replies" that don't actually get sent to a client (e.g.
|
|
90
|
-
// upgrade/pulse replies).
|
|
91
|
-
maybe(reply_message.header.invalid() == null);
|
|
92
|
-
assert((reply_message.header.client == 0) == (client_index == null));
|
|
93
|
-
assert(reply_message.header.client == prepare_message.header.client);
|
|
94
|
-
assert(reply_message.header.request == prepare_message.header.request);
|
|
95
|
-
assert(reply_message.header.command == .reply);
|
|
96
|
-
assert(reply_message.header.operation == prepare_message.header.operation);
|
|
97
|
-
assert(reply_message.header.op == prepare_message.header.op);
|
|
98
|
-
|
|
99
|
-
var pending_replies = sequence.stalled_queue.iterator();
|
|
100
|
-
while (pending_replies.next()) |pending| {
|
|
101
|
-
assert(reply_message.header.op != pending.reply.header.op);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
sequence.stalled_queue.add(.{
|
|
105
|
-
.client_index = client_index,
|
|
106
|
-
.prepare = sequence.clone_message(prepare_message.base_const()).into(.prepare).?,
|
|
107
|
-
.reply = sequence.clone_message(reply_message.base_const()).into(.reply).?,
|
|
108
|
-
}) catch unreachable;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
pub fn contains(sequence: *ReplySequence, reply: *const Message.Reply) bool {
|
|
112
|
-
assert(reply.header.command == .reply);
|
|
113
|
-
|
|
114
|
-
var pending_replies = sequence.stalled_queue.iterator();
|
|
115
|
-
while (pending_replies.next()) |pending| {
|
|
116
|
-
if (reply.header.op == pending.reply.header.op) {
|
|
117
|
-
assert(reply.header.checksum == pending.reply.header.checksum);
|
|
118
|
-
return true;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
return false;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// TODO(Zig): This type signature could be *const once std.PriorityQueue.peek() is updated.
|
|
125
|
-
pub fn peek(sequence: *ReplySequence, op: u64) ?PendingReply {
|
|
126
|
-
assert(sequence.stalled_queue.count() <= stalled_queue_capacity);
|
|
127
|
-
|
|
128
|
-
const commit = sequence.stalled_queue.peek() orelse return null;
|
|
129
|
-
if (commit.reply.header.op == op) {
|
|
130
|
-
return commit;
|
|
131
|
-
} else {
|
|
132
|
-
assert(commit.reply.header.op > op);
|
|
133
|
-
return null;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
pub fn next(sequence: *ReplySequence) void {
|
|
138
|
-
const commit = sequence.stalled_queue.remove();
|
|
139
|
-
sequence.message_pool.unref(commit.reply);
|
|
140
|
-
sequence.message_pool.unref(commit.prepare);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/// Copy the message from a Client's MessagePool to the ReplySequence's MessagePool.
|
|
144
|
-
///
|
|
145
|
-
/// The client has a finite amount of messages in its pool, and the ReplySequence needs to hold
|
|
146
|
-
/// onto prepares/replies until all preceding prepares/replies have arrived.
|
|
147
|
-
///
|
|
148
|
-
/// Returns the ReplySequence's message.
|
|
149
|
-
fn clone_message(sequence: *ReplySequence, message_client: *const Message) *Message {
|
|
150
|
-
const message_sequence = sequence.message_pool.get_message(null);
|
|
151
|
-
stdx.copy_disjoint(.exact, u8, message_sequence.buffer, message_client.buffer);
|
|
152
|
-
return message_sequence;
|
|
153
|
-
}
|
|
154
|
-
};
|