tigerbeetle-node 0.11.12 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/README.md +212 -196
  2. package/dist/bin/aarch64-linux-gnu/client.node +0 -0
  3. package/dist/bin/aarch64-linux-musl/client.node +0 -0
  4. package/dist/bin/aarch64-macos/client.node +0 -0
  5. package/dist/bin/x86_64-linux-gnu/client.node +0 -0
  6. package/dist/bin/x86_64-linux-musl/client.node +0 -0
  7. package/dist/bin/x86_64-macos/client.node +0 -0
  8. package/dist/index.js +33 -1
  9. package/dist/index.js.map +1 -1
  10. package/package-lock.json +66 -0
  11. package/package.json +8 -17
  12. package/src/index.ts +56 -1
  13. package/src/node.zig +10 -9
  14. package/dist/.client.node.sha256 +0 -1
  15. package/scripts/build_lib.sh +0 -61
  16. package/scripts/download_node_headers.sh +0 -32
  17. package/src/tigerbeetle/scripts/benchmark.bat +0 -48
  18. package/src/tigerbeetle/scripts/benchmark.sh +0 -66
  19. package/src/tigerbeetle/scripts/confirm_image.sh +0 -44
  20. package/src/tigerbeetle/scripts/fuzz_loop.sh +0 -15
  21. package/src/tigerbeetle/scripts/fuzz_unique_errors.sh +0 -7
  22. package/src/tigerbeetle/scripts/install.bat +0 -7
  23. package/src/tigerbeetle/scripts/install.sh +0 -21
  24. package/src/tigerbeetle/scripts/install_zig.bat +0 -113
  25. package/src/tigerbeetle/scripts/install_zig.sh +0 -90
  26. package/src/tigerbeetle/scripts/lint.zig +0 -199
  27. package/src/tigerbeetle/scripts/pre-commit.sh +0 -9
  28. package/src/tigerbeetle/scripts/scripts/benchmark.bat +0 -48
  29. package/src/tigerbeetle/scripts/scripts/benchmark.sh +0 -66
  30. package/src/tigerbeetle/scripts/scripts/confirm_image.sh +0 -44
  31. package/src/tigerbeetle/scripts/scripts/fuzz_loop.sh +0 -15
  32. package/src/tigerbeetle/scripts/scripts/fuzz_unique_errors.sh +0 -7
  33. package/src/tigerbeetle/scripts/scripts/install.bat +0 -7
  34. package/src/tigerbeetle/scripts/scripts/install.sh +0 -21
  35. package/src/tigerbeetle/scripts/scripts/install_zig.bat +0 -113
  36. package/src/tigerbeetle/scripts/scripts/install_zig.sh +0 -90
  37. package/src/tigerbeetle/scripts/scripts/lint.zig +0 -199
  38. package/src/tigerbeetle/scripts/scripts/pre-commit.sh +0 -9
  39. package/src/tigerbeetle/scripts/scripts/shellcheck.sh +0 -5
  40. package/src/tigerbeetle/scripts/scripts/tests_on_alpine.sh +0 -10
  41. package/src/tigerbeetle/scripts/scripts/tests_on_ubuntu.sh +0 -14
  42. package/src/tigerbeetle/scripts/scripts/upgrade_ubuntu_kernel.sh +0 -48
  43. package/src/tigerbeetle/scripts/scripts/validate_docs.sh +0 -23
  44. package/src/tigerbeetle/scripts/scripts/vr_state_enumerate +0 -46
  45. package/src/tigerbeetle/scripts/shellcheck.sh +0 -5
  46. package/src/tigerbeetle/scripts/tests_on_alpine.sh +0 -10
  47. package/src/tigerbeetle/scripts/tests_on_ubuntu.sh +0 -14
  48. package/src/tigerbeetle/scripts/upgrade_ubuntu_kernel.sh +0 -48
  49. package/src/tigerbeetle/scripts/validate_docs.sh +0 -23
  50. package/src/tigerbeetle/scripts/vr_state_enumerate +0 -46
  51. package/src/tigerbeetle/src/benchmark.zig +0 -314
  52. package/src/tigerbeetle/src/config.zig +0 -234
  53. package/src/tigerbeetle/src/constants.zig +0 -436
  54. package/src/tigerbeetle/src/ewah.zig +0 -286
  55. package/src/tigerbeetle/src/ewah_benchmark.zig +0 -120
  56. package/src/tigerbeetle/src/ewah_fuzz.zig +0 -130
  57. package/src/tigerbeetle/src/fifo.zig +0 -120
  58. package/src/tigerbeetle/src/io/benchmark.zig +0 -213
  59. package/src/tigerbeetle/src/io/darwin.zig +0 -814
  60. package/src/tigerbeetle/src/io/linux.zig +0 -1062
  61. package/src/tigerbeetle/src/io/test.zig +0 -643
  62. package/src/tigerbeetle/src/io/windows.zig +0 -1183
  63. package/src/tigerbeetle/src/io.zig +0 -34
  64. package/src/tigerbeetle/src/iops.zig +0 -107
  65. package/src/tigerbeetle/src/lsm/README.md +0 -308
  66. package/src/tigerbeetle/src/lsm/binary_search.zig +0 -341
  67. package/src/tigerbeetle/src/lsm/bloom_filter.zig +0 -125
  68. package/src/tigerbeetle/src/lsm/compaction.zig +0 -603
  69. package/src/tigerbeetle/src/lsm/composite_key.zig +0 -77
  70. package/src/tigerbeetle/src/lsm/direction.zig +0 -11
  71. package/src/tigerbeetle/src/lsm/eytzinger.zig +0 -587
  72. package/src/tigerbeetle/src/lsm/eytzinger_benchmark.zig +0 -330
  73. package/src/tigerbeetle/src/lsm/forest.zig +0 -204
  74. package/src/tigerbeetle/src/lsm/forest_fuzz.zig +0 -401
  75. package/src/tigerbeetle/src/lsm/grid.zig +0 -573
  76. package/src/tigerbeetle/src/lsm/groove.zig +0 -972
  77. package/src/tigerbeetle/src/lsm/k_way_merge.zig +0 -474
  78. package/src/tigerbeetle/src/lsm/level_iterator.zig +0 -332
  79. package/src/tigerbeetle/src/lsm/manifest.zig +0 -617
  80. package/src/tigerbeetle/src/lsm/manifest_level.zig +0 -877
  81. package/src/tigerbeetle/src/lsm/manifest_log.zig +0 -789
  82. package/src/tigerbeetle/src/lsm/manifest_log_fuzz.zig +0 -691
  83. package/src/tigerbeetle/src/lsm/merge_iterator.zig +0 -106
  84. package/src/tigerbeetle/src/lsm/node_pool.zig +0 -235
  85. package/src/tigerbeetle/src/lsm/posted_groove.zig +0 -378
  86. package/src/tigerbeetle/src/lsm/segmented_array.zig +0 -1328
  87. package/src/tigerbeetle/src/lsm/segmented_array_benchmark.zig +0 -148
  88. package/src/tigerbeetle/src/lsm/segmented_array_fuzz.zig +0 -9
  89. package/src/tigerbeetle/src/lsm/set_associative_cache.zig +0 -850
  90. package/src/tigerbeetle/src/lsm/table.zig +0 -1031
  91. package/src/tigerbeetle/src/lsm/table_immutable.zig +0 -203
  92. package/src/tigerbeetle/src/lsm/table_iterator.zig +0 -340
  93. package/src/tigerbeetle/src/lsm/table_mutable.zig +0 -220
  94. package/src/tigerbeetle/src/lsm/test.zig +0 -438
  95. package/src/tigerbeetle/src/lsm/tree.zig +0 -1193
  96. package/src/tigerbeetle/src/lsm/tree_fuzz.zig +0 -474
  97. package/src/tigerbeetle/src/message_bus.zig +0 -1012
  98. package/src/tigerbeetle/src/message_pool.zig +0 -156
  99. package/src/tigerbeetle/src/ring_buffer.zig +0 -399
  100. package/src/tigerbeetle/src/simulator.zig +0 -569
  101. package/src/tigerbeetle/src/state_machine/auditor.zig +0 -577
  102. package/src/tigerbeetle/src/state_machine/workload.zig +0 -883
  103. package/src/tigerbeetle/src/state_machine.zig +0 -1881
  104. package/src/tigerbeetle/src/static_allocator.zig +0 -65
  105. package/src/tigerbeetle/src/stdx.zig +0 -162
  106. package/src/tigerbeetle/src/storage.zig +0 -393
  107. package/src/tigerbeetle/src/testing/cluster/message_bus.zig +0 -82
  108. package/src/tigerbeetle/src/testing/cluster/network.zig +0 -237
  109. package/src/tigerbeetle/src/testing/cluster/state_checker.zig +0 -169
  110. package/src/tigerbeetle/src/testing/cluster/storage_checker.zig +0 -202
  111. package/src/tigerbeetle/src/testing/cluster.zig +0 -443
  112. package/src/tigerbeetle/src/testing/fuzz.zig +0 -140
  113. package/src/tigerbeetle/src/testing/hash_log.zig +0 -66
  114. package/src/tigerbeetle/src/testing/id.zig +0 -99
  115. package/src/tigerbeetle/src/testing/packet_simulator.zig +0 -364
  116. package/src/tigerbeetle/src/testing/priority_queue.zig +0 -645
  117. package/src/tigerbeetle/src/testing/reply_sequence.zig +0 -139
  118. package/src/tigerbeetle/src/testing/state_machine.zig +0 -249
  119. package/src/tigerbeetle/src/testing/storage.zig +0 -757
  120. package/src/tigerbeetle/src/testing/table.zig +0 -247
  121. package/src/tigerbeetle/src/testing/time.zig +0 -84
  122. package/src/tigerbeetle/src/tigerbeetle.zig +0 -227
  123. package/src/tigerbeetle/src/time.zig +0 -112
  124. package/src/tigerbeetle/src/tracer.zig +0 -529
  125. package/src/tigerbeetle/src/unit_tests.zig +0 -42
  126. package/src/tigerbeetle/src/vopr.zig +0 -495
  127. package/src/tigerbeetle/src/vsr/README.md +0 -209
  128. package/src/tigerbeetle/src/vsr/client.zig +0 -544
  129. package/src/tigerbeetle/src/vsr/clock.zig +0 -853
  130. package/src/tigerbeetle/src/vsr/journal.zig +0 -2413
  131. package/src/tigerbeetle/src/vsr/journal_format_fuzz.zig +0 -111
  132. package/src/tigerbeetle/src/vsr/marzullo.zig +0 -309
  133. package/src/tigerbeetle/src/vsr/replica.zig +0 -6381
  134. package/src/tigerbeetle/src/vsr/replica_format.zig +0 -219
  135. package/src/tigerbeetle/src/vsr/superblock.zig +0 -1631
  136. package/src/tigerbeetle/src/vsr/superblock_client_table.zig +0 -256
  137. package/src/tigerbeetle/src/vsr/superblock_free_set.zig +0 -929
  138. package/src/tigerbeetle/src/vsr/superblock_free_set_fuzz.zig +0 -334
  139. package/src/tigerbeetle/src/vsr/superblock_fuzz.zig +0 -390
  140. package/src/tigerbeetle/src/vsr/superblock_manifest.zig +0 -615
  141. package/src/tigerbeetle/src/vsr/superblock_quorums.zig +0 -394
  142. package/src/tigerbeetle/src/vsr/superblock_quorums_fuzz.zig +0 -314
  143. package/src/tigerbeetle/src/vsr.zig +0 -1352
@@ -1,99 +0,0 @@
1
- const std = @import("std");
2
-
3
- /// Permute indices (or other encoded data) into ids to:
4
- ///
5
- /// * test different patterns of ids (e.g. random, ascending, descending), and
6
- /// * allow the original index to recovered from the id, enabling less stateful testing.
7
- ///
8
- pub const IdPermutation = union(enum) {
9
- /// Ascending indices become ascending ids.
10
- identity: void,
11
-
12
- /// Ascending indices become descending ids.
13
- inversion: void,
14
-
15
- /// Ascending indices alternate between ascending/descending (e.g. 1,100,3,98,…).
16
- zigzag: void,
17
-
18
- /// Ascending indices become pseudo-UUIDs.
19
- ///
20
- /// Sandwich the index "data" between random bits — this randomizes the id's prefix and suffix,
21
- /// but the index is easily recovered:
22
- ///
23
- /// * id_bits[_0.._32] = random
24
- /// * id_bits[32.._96] = data
25
- /// * id_bits[96..128] = random
26
- random: u64,
27
-
28
- pub fn encode(self: *const IdPermutation, data: usize) u128 {
29
- return switch (self.*) {
30
- .identity => data,
31
- .inversion => std.math.maxInt(u128) - @as(u128, data),
32
- .zigzag => {
33
- if (data % 2 == 0) {
34
- return data;
35
- } else {
36
- // -1 to stay odd.
37
- return std.math.maxInt(u128) - @as(u128, data) -% 1;
38
- }
39
- },
40
- .random => |seed| {
41
- var prng = std.rand.DefaultPrng.init(seed +% data);
42
- const random = prng.random();
43
- const random_mask = ~@as(u128, std.math.maxInt(u64) << 32);
44
- const random_bits = random_mask & random.int(u128);
45
- return @as(u128, data) << 32 | random_bits;
46
- },
47
- };
48
- }
49
-
50
- pub fn decode(self: *const IdPermutation, id: u128) usize {
51
- return switch (self.*) {
52
- .identity => @intCast(usize, id),
53
- .inversion => @intCast(usize, std.math.maxInt(u128) - id),
54
- .zigzag => {
55
- if (id % 2 == 0) {
56
- return @intCast(usize, id);
57
- } else {
58
- // -1 to stay odd.
59
- return @intCast(usize, std.math.maxInt(u128) - id -% 1);
60
- }
61
- },
62
- .random => @truncate(usize, id >> 32),
63
- };
64
- }
65
-
66
- pub fn generate(random: std.rand.Random) IdPermutation {
67
- return switch (random.uintLessThan(usize, 4)) {
68
- 0 => .{ .identity = {} },
69
- 1 => .{ .inversion = {} },
70
- 2 => .{ .zigzag = {} },
71
- 3 => .{ .random = random.int(u64) },
72
- else => unreachable,
73
- };
74
- }
75
- };
76
-
77
- test "IdPermutation" {
78
- var prng = std.rand.DefaultPrng.init(123);
79
- const random = prng.random();
80
-
81
- for ([_]IdPermutation{
82
- .{ .identity = {} },
83
- .{ .inversion = {} },
84
- .{ .zigzag = {} },
85
- .{ .random = random.int(u64) },
86
- }) |permutation| {
87
- var i: usize = 0;
88
- while (i < 20) : (i += 1) {
89
- const r = random.int(usize);
90
- try test_id_permutation(permutation, r);
91
- try test_id_permutation(permutation, i);
92
- try test_id_permutation(permutation, std.math.maxInt(usize) - i);
93
- }
94
- }
95
- }
96
-
97
- fn test_id_permutation(permutation: IdPermutation, value: usize) !void {
98
- try std.testing.expectEqual(value, permutation.decode(permutation.encode(value)));
99
- }
@@ -1,364 +0,0 @@
1
- const std = @import("std");
2
- const assert = std.debug.assert;
3
- const math = std.math;
4
-
5
- const log = std.log.scoped(.packet_simulator);
6
- const vsr = @import("../vsr.zig");
7
- const PriorityQueue = @import("./priority_queue.zig").PriorityQueue;
8
- const fuzz = @import("./fuzz.zig");
9
-
10
- pub const PacketSimulatorOptions = struct {
11
- replica_count: u8,
12
- client_count: u8,
13
- seed: u64,
14
-
15
- /// Mean for the exponential distribution used to calculate forward delay.
16
- one_way_delay_mean: u64,
17
- one_way_delay_min: u64,
18
-
19
- packet_loss_probability: u8 = 0,
20
- packet_replay_probability: u8 = 0,
21
-
22
- /// How the partitions should be generated
23
- partition_mode: PartitionMode = .none,
24
-
25
- /// Probability per tick that a partition will occur
26
- partition_probability: u8 = 0,
27
-
28
- /// Probability per tick that a partition will resolve
29
- unpartition_probability: u8 = 0,
30
-
31
- /// Minimum time a partition lasts
32
- partition_stability: u32 = 0,
33
-
34
- /// Minimum time the cluster is fully connected until it is partitioned again
35
- unpartition_stability: u32 = 0,
36
-
37
- /// The maximum number of in-flight packets a path can have before packets are randomly dropped.
38
- path_maximum_capacity: u8,
39
-
40
- /// Mean for the exponential distribution used to calculate how long a path is clogged for.
41
- path_clog_duration_mean: u64,
42
- path_clog_probability: u8,
43
- };
44
-
45
- pub const Path = struct {
46
- source: u8,
47
- target: u8,
48
- };
49
-
50
- /// Determines how the partitions are created. Partitions
51
- /// are two-way, i.e. if i cannot communicate with j, then
52
- /// j cannot communicate with i.
53
- ///
54
- /// Only replicas are partitioned. There will always be exactly two partitions.
55
- pub const PartitionMode = enum {
56
- /// Disable automatic partitioning.
57
- none,
58
-
59
- /// Draws the size of the partition uniformly at random from (1, n-1).
60
- /// Replicas are randomly assigned a partition.
61
- uniform_size,
62
-
63
- /// Assigns each node to a partition uniformly at random. This biases towards
64
- /// equal-size partitions.
65
- uniform_partition,
66
-
67
- /// Isolates exactly one replica.
68
- isolate_single,
69
- };
70
-
71
- pub fn PacketSimulatorType(comptime Packet: type) type {
72
- return struct {
73
- const Self = @This();
74
-
75
- const LinkPacket = struct {
76
- expiry: u64,
77
- callback: fn (packet: Packet, path: Path) void,
78
- packet: Packet,
79
- };
80
-
81
- const Link = struct {
82
- queue: PriorityQueue(LinkPacket, void, Self.order_packets),
83
- /// When false, packets sent on the path are not delivered.
84
- enabled: bool = true,
85
- /// We can arbitrary clog a path until a tick.
86
- clogged_till: u64 = 0,
87
- };
88
-
89
- options: PacketSimulatorOptions,
90
- prng: std.rand.DefaultPrng,
91
- ticks: u64 = 0,
92
-
93
- /// A send and receive path between each node in the network.
94
- /// Indexed by path_index().
95
- links: []Link,
96
-
97
- /// Scratch space for automatically generating partitions.
98
- /// The "source of truth" for partitions is links[*].enabled.
99
- auto_partition: []bool,
100
- auto_partition_active: bool,
101
- auto_partition_replicas: []u8,
102
- auto_partition_stability: u32,
103
-
104
- pub fn init(allocator: std.mem.Allocator, options: PacketSimulatorOptions) !Self {
105
- assert(options.replica_count > 0);
106
- assert(options.one_way_delay_mean >= options.one_way_delay_min);
107
-
108
- const node_count_ = options.replica_count + options.client_count;
109
- const links = try allocator.alloc(Link, @as(usize, node_count_) * node_count_);
110
- errdefer allocator.free(links);
111
-
112
- for (links) |*link, i| {
113
- errdefer for (links[0..i]) |l| l.queue.deinit();
114
-
115
- const queue = PriorityQueue(LinkPacket, void, Self.order_packets).init(allocator, {});
116
- try link.queue.ensureTotalCapacity(options.path_maximum_capacity);
117
- link.* = .{ .queue = queue };
118
- }
119
- errdefer for (links) |link| link.queue.deinit();
120
-
121
- const auto_partition = try allocator.alloc(bool, @as(usize, options.replica_count));
122
- errdefer allocator.free(auto_partition);
123
- std.mem.set(bool, auto_partition, false);
124
-
125
- const auto_partition_replicas = try allocator.alloc(u8, @as(usize, options.replica_count));
126
- errdefer allocator.free(auto_partition_replicas);
127
- for (auto_partition_replicas) |*replica, i| replica.* = @intCast(u8, i);
128
-
129
- return Self{
130
- .options = options,
131
- .prng = std.rand.DefaultPrng.init(options.seed),
132
- .links = links,
133
-
134
- .auto_partition_active = false,
135
- .auto_partition = auto_partition,
136
- .auto_partition_replicas = auto_partition_replicas,
137
- .auto_partition_stability = options.unpartition_stability,
138
- };
139
- }
140
-
141
- pub fn deinit(self: *Self, allocator: std.mem.Allocator) void {
142
- for (self.links) |*link| {
143
- while (link.queue.peek()) |_| link.queue.remove().packet.deinit();
144
- link.queue.deinit();
145
- }
146
-
147
- allocator.free(self.links);
148
- allocator.free(self.auto_partition);
149
- allocator.free(self.auto_partition_replicas);
150
- }
151
-
152
- fn order_packets(context: void, a: LinkPacket, b: LinkPacket) math.Order {
153
- _ = context;
154
-
155
- return math.order(a.expiry, b.expiry);
156
- }
157
-
158
- fn node_count(self: Self) usize {
159
- return self.options.replica_count + self.options.client_count;
160
- }
161
-
162
- fn path_index(self: Self, path: Path) usize {
163
- assert(path.source < self.node_count());
164
- assert(path.target < self.node_count());
165
-
166
- return @as(usize, path.source) * self.node_count() + path.target;
167
- }
168
-
169
- fn should_drop(self: *Self) bool {
170
- return self.prng.random().uintAtMost(u8, 100) < self.options.packet_loss_probability;
171
- }
172
-
173
- fn is_clogged(self: *Self, path: Path) bool {
174
- return self.links[self.path_index(path)].clogged_till > self.ticks;
175
- }
176
-
177
- fn should_clog(self: *Self, path: Path) bool {
178
- _ = path;
179
-
180
- return self.prng.random().uintAtMost(u8, 100) < self.options.path_clog_probability;
181
- }
182
-
183
- fn clog_for(self: *Self, path: Path, ticks: u64) void {
184
- const clog_expiry = &self.links[self.path_index(path)].clogged_till;
185
- clog_expiry.* = self.ticks + ticks;
186
- log.debug("Path path.source={} path.target={} clogged for ticks={}", .{
187
- path.source,
188
- path.target,
189
- ticks,
190
- });
191
- }
192
-
193
- fn should_replay(self: *Self) bool {
194
- return self.prng.random().uintAtMost(u8, 100) < self.options.packet_replay_probability;
195
- }
196
-
197
- fn should_partition(self: *Self) bool {
198
- return self.prng.random().uintAtMost(u8, 100) < self.options.partition_probability;
199
- }
200
-
201
- fn should_unpartition(self: *Self) bool {
202
- return self.prng.random().uintAtMost(u8, 100) < self.options.unpartition_probability;
203
- }
204
-
205
- /// Return a value produced using an exponential distribution with
206
- /// the minimum and mean specified in self.options
207
- fn one_way_delay(self: *Self) u64 {
208
- const min = self.options.one_way_delay_min;
209
- const mean = self.options.one_way_delay_mean;
210
- return min + fuzz.random_int_exponential(self.prng.random(), u64, mean - min);
211
- }
212
-
213
- /// Partitions the network. Guaranteed to isolate at least one replica.
214
- fn auto_partition_network(self: *Self) void {
215
- assert(self.options.replica_count > 1);
216
-
217
- var partition = self.auto_partition;
218
- switch (self.options.partition_mode) {
219
- .none => std.mem.set(bool, partition, false),
220
- .uniform_size => {
221
- // Exclude cases partition_size == 0 and partition_size == replica_count
222
- const partition_size =
223
- 1 + self.prng.random().uintAtMost(u8, self.options.replica_count - 2);
224
- self.prng.random().shuffle(u8, self.auto_partition_replicas);
225
- for (self.auto_partition_replicas) |r, i| {
226
- partition[r] = i < partition_size;
227
- }
228
- },
229
- .uniform_partition => {
230
- var only_same = true;
231
- partition[0] = self.prng.random().uintLessThan(u8, 2) == 1;
232
-
233
- var i: usize = 1;
234
- while (i < self.options.replica_count) : (i += 1) {
235
- partition[i] = self.prng.random().uintLessThan(u8, 2) == 1;
236
- only_same =
237
- only_same and (partition[i - 1] == partition[i]);
238
- }
239
-
240
- if (only_same) {
241
- const n = self.prng.random().uintLessThan(u8, self.options.replica_count);
242
- self.auto_partition[n] = true;
243
- }
244
- },
245
- .isolate_single => {
246
- std.mem.set(bool, partition, false);
247
- const n = self.prng.random().uintLessThan(u8, self.options.replica_count);
248
- partition[n] = true;
249
- },
250
- }
251
-
252
- self.auto_partition_active = true;
253
- self.auto_partition_stability = self.options.partition_stability;
254
-
255
- var from: u8 = 0;
256
- while (from < self.node_count()) : (from += 1) {
257
- var to: u8 = 0;
258
- while (to < self.node_count()) : (to += 1) {
259
- const path = .{ .source = from, .target = to };
260
- self.links[self.path_index(path)].enabled = from >= self.options.replica_count or
261
- to >= self.options.replica_count or partition[from] == partition[to];
262
- }
263
- }
264
- }
265
-
266
- pub fn tick(self: *Self) void {
267
- self.ticks += 1;
268
-
269
- if (self.auto_partition_stability > 0) {
270
- self.auto_partition_stability -= 1;
271
- } else {
272
- if (self.auto_partition_active) {
273
- if (self.should_unpartition()) {
274
- self.auto_partition_active = false;
275
- self.auto_partition_stability = self.options.unpartition_stability;
276
- std.mem.set(bool, self.auto_partition, false);
277
- for (self.links) |*link| link.enabled = true;
278
- log.warn("unpartitioned network: partition={d}", .{self.auto_partition});
279
- }
280
- } else {
281
- if (self.options.replica_count > 1 and self.should_partition()) {
282
- self.auto_partition_network();
283
- log.warn("partitioned network: partition={d}", .{self.auto_partition});
284
- }
285
- }
286
- }
287
-
288
- var from: u8 = 0;
289
- while (from < self.node_count()) : (from += 1) {
290
- var to: u8 = 0;
291
- while (to < self.node_count()) : (to += 1) {
292
- const path = .{ .source = from, .target = to };
293
- if (self.is_clogged(path)) continue;
294
-
295
- const queue = &self.links[self.path_index(path)].queue;
296
- while (queue.peek()) |*link_packet| {
297
- if (link_packet.expiry > self.ticks) break;
298
- _ = queue.remove();
299
-
300
- if (!self.links[self.path_index(path)].enabled) {
301
- log.warn("dropped packet (different partitions): from={} to={}", .{ from, to });
302
- link_packet.packet.deinit();
303
- continue;
304
- }
305
-
306
- if (self.should_drop()) {
307
- log.warn("dropped packet from={} to={}", .{ from, to });
308
- link_packet.packet.deinit();
309
- continue;
310
- }
311
-
312
- if (self.should_replay()) {
313
- self.submit_packet(link_packet.packet, link_packet.callback, path);
314
-
315
- log.debug("replayed packet from={} to={}", .{ from, to });
316
-
317
- link_packet.callback(link_packet.packet, path);
318
- } else {
319
- log.debug("delivering packet from={} to={}", .{ from, to });
320
- link_packet.callback(link_packet.packet, path);
321
- link_packet.packet.deinit();
322
- }
323
- }
324
-
325
- const reverse_path: Path = .{ .source = to, .target = from };
326
-
327
- if (self.should_clog(reverse_path)) {
328
- const ticks = fuzz.random_int_exponential(
329
- self.prng.random(),
330
- u64,
331
- self.options.path_clog_duration_mean,
332
- );
333
- self.clog_for(reverse_path, ticks);
334
- }
335
- }
336
- }
337
- }
338
-
339
- pub fn submit_packet(
340
- self: *Self,
341
- packet: Packet,
342
- callback: fn (packet: Packet, path: Path) void,
343
- path: Path,
344
- ) void {
345
- const queue = &self.links[self.path_index(path)].queue;
346
- var queue_length = queue.count();
347
- if (queue_length + 1 > self.options.path_maximum_capacity) {
348
- const index = self.prng.random().uintLessThanBiased(u64, queue_length);
349
- const link_packet = queue.removeIndex(index);
350
- link_packet.packet.deinit();
351
- log.warn("submit_packet: {} reached capacity, dropped packet={}", .{
352
- path,
353
- index,
354
- });
355
- }
356
-
357
- queue.add(.{
358
- .expiry = self.ticks + self.one_way_delay(),
359
- .packet = packet,
360
- .callback = callback,
361
- }) catch unreachable;
362
- }
363
- };
364
- }