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.
- package/README.md +212 -196
- package/dist/bin/aarch64-linux-gnu/client.node +0 -0
- package/dist/bin/aarch64-linux-musl/client.node +0 -0
- package/dist/bin/aarch64-macos/client.node +0 -0
- package/dist/bin/x86_64-linux-gnu/client.node +0 -0
- package/dist/bin/x86_64-linux-musl/client.node +0 -0
- package/dist/bin/x86_64-macos/client.node +0 -0
- package/dist/index.js +33 -1
- package/dist/index.js.map +1 -1
- package/package-lock.json +66 -0
- package/package.json +8 -17
- package/src/index.ts +56 -1
- package/src/node.zig +10 -9
- package/dist/.client.node.sha256 +0 -1
- package/scripts/build_lib.sh +0 -61
- package/scripts/download_node_headers.sh +0 -32
- package/src/tigerbeetle/scripts/benchmark.bat +0 -48
- package/src/tigerbeetle/scripts/benchmark.sh +0 -66
- package/src/tigerbeetle/scripts/confirm_image.sh +0 -44
- package/src/tigerbeetle/scripts/fuzz_loop.sh +0 -15
- package/src/tigerbeetle/scripts/fuzz_unique_errors.sh +0 -7
- package/src/tigerbeetle/scripts/install.bat +0 -7
- package/src/tigerbeetle/scripts/install.sh +0 -21
- package/src/tigerbeetle/scripts/install_zig.bat +0 -113
- package/src/tigerbeetle/scripts/install_zig.sh +0 -90
- package/src/tigerbeetle/scripts/lint.zig +0 -199
- package/src/tigerbeetle/scripts/pre-commit.sh +0 -9
- package/src/tigerbeetle/scripts/scripts/benchmark.bat +0 -48
- package/src/tigerbeetle/scripts/scripts/benchmark.sh +0 -66
- package/src/tigerbeetle/scripts/scripts/confirm_image.sh +0 -44
- package/src/tigerbeetle/scripts/scripts/fuzz_loop.sh +0 -15
- package/src/tigerbeetle/scripts/scripts/fuzz_unique_errors.sh +0 -7
- package/src/tigerbeetle/scripts/scripts/install.bat +0 -7
- package/src/tigerbeetle/scripts/scripts/install.sh +0 -21
- package/src/tigerbeetle/scripts/scripts/install_zig.bat +0 -113
- package/src/tigerbeetle/scripts/scripts/install_zig.sh +0 -90
- package/src/tigerbeetle/scripts/scripts/lint.zig +0 -199
- package/src/tigerbeetle/scripts/scripts/pre-commit.sh +0 -9
- package/src/tigerbeetle/scripts/scripts/shellcheck.sh +0 -5
- package/src/tigerbeetle/scripts/scripts/tests_on_alpine.sh +0 -10
- package/src/tigerbeetle/scripts/scripts/tests_on_ubuntu.sh +0 -14
- package/src/tigerbeetle/scripts/scripts/upgrade_ubuntu_kernel.sh +0 -48
- package/src/tigerbeetle/scripts/scripts/validate_docs.sh +0 -23
- package/src/tigerbeetle/scripts/scripts/vr_state_enumerate +0 -46
- package/src/tigerbeetle/scripts/shellcheck.sh +0 -5
- package/src/tigerbeetle/scripts/tests_on_alpine.sh +0 -10
- package/src/tigerbeetle/scripts/tests_on_ubuntu.sh +0 -14
- package/src/tigerbeetle/scripts/upgrade_ubuntu_kernel.sh +0 -48
- package/src/tigerbeetle/scripts/validate_docs.sh +0 -23
- package/src/tigerbeetle/scripts/vr_state_enumerate +0 -46
- package/src/tigerbeetle/src/benchmark.zig +0 -314
- package/src/tigerbeetle/src/config.zig +0 -234
- package/src/tigerbeetle/src/constants.zig +0 -436
- package/src/tigerbeetle/src/ewah.zig +0 -286
- package/src/tigerbeetle/src/ewah_benchmark.zig +0 -120
- package/src/tigerbeetle/src/ewah_fuzz.zig +0 -130
- package/src/tigerbeetle/src/fifo.zig +0 -120
- package/src/tigerbeetle/src/io/benchmark.zig +0 -213
- package/src/tigerbeetle/src/io/darwin.zig +0 -814
- package/src/tigerbeetle/src/io/linux.zig +0 -1062
- package/src/tigerbeetle/src/io/test.zig +0 -643
- package/src/tigerbeetle/src/io/windows.zig +0 -1183
- package/src/tigerbeetle/src/io.zig +0 -34
- package/src/tigerbeetle/src/iops.zig +0 -107
- package/src/tigerbeetle/src/lsm/README.md +0 -308
- package/src/tigerbeetle/src/lsm/binary_search.zig +0 -341
- package/src/tigerbeetle/src/lsm/bloom_filter.zig +0 -125
- package/src/tigerbeetle/src/lsm/compaction.zig +0 -603
- package/src/tigerbeetle/src/lsm/composite_key.zig +0 -77
- package/src/tigerbeetle/src/lsm/direction.zig +0 -11
- package/src/tigerbeetle/src/lsm/eytzinger.zig +0 -587
- package/src/tigerbeetle/src/lsm/eytzinger_benchmark.zig +0 -330
- package/src/tigerbeetle/src/lsm/forest.zig +0 -204
- package/src/tigerbeetle/src/lsm/forest_fuzz.zig +0 -401
- package/src/tigerbeetle/src/lsm/grid.zig +0 -573
- package/src/tigerbeetle/src/lsm/groove.zig +0 -972
- package/src/tigerbeetle/src/lsm/k_way_merge.zig +0 -474
- package/src/tigerbeetle/src/lsm/level_iterator.zig +0 -332
- package/src/tigerbeetle/src/lsm/manifest.zig +0 -617
- package/src/tigerbeetle/src/lsm/manifest_level.zig +0 -877
- package/src/tigerbeetle/src/lsm/manifest_log.zig +0 -789
- package/src/tigerbeetle/src/lsm/manifest_log_fuzz.zig +0 -691
- package/src/tigerbeetle/src/lsm/merge_iterator.zig +0 -106
- package/src/tigerbeetle/src/lsm/node_pool.zig +0 -235
- package/src/tigerbeetle/src/lsm/posted_groove.zig +0 -378
- package/src/tigerbeetle/src/lsm/segmented_array.zig +0 -1328
- package/src/tigerbeetle/src/lsm/segmented_array_benchmark.zig +0 -148
- package/src/tigerbeetle/src/lsm/segmented_array_fuzz.zig +0 -9
- package/src/tigerbeetle/src/lsm/set_associative_cache.zig +0 -850
- package/src/tigerbeetle/src/lsm/table.zig +0 -1031
- package/src/tigerbeetle/src/lsm/table_immutable.zig +0 -203
- package/src/tigerbeetle/src/lsm/table_iterator.zig +0 -340
- package/src/tigerbeetle/src/lsm/table_mutable.zig +0 -220
- package/src/tigerbeetle/src/lsm/test.zig +0 -438
- package/src/tigerbeetle/src/lsm/tree.zig +0 -1193
- package/src/tigerbeetle/src/lsm/tree_fuzz.zig +0 -474
- package/src/tigerbeetle/src/message_bus.zig +0 -1012
- package/src/tigerbeetle/src/message_pool.zig +0 -156
- package/src/tigerbeetle/src/ring_buffer.zig +0 -399
- package/src/tigerbeetle/src/simulator.zig +0 -569
- package/src/tigerbeetle/src/state_machine/auditor.zig +0 -577
- package/src/tigerbeetle/src/state_machine/workload.zig +0 -883
- package/src/tigerbeetle/src/state_machine.zig +0 -1881
- package/src/tigerbeetle/src/static_allocator.zig +0 -65
- package/src/tigerbeetle/src/stdx.zig +0 -162
- package/src/tigerbeetle/src/storage.zig +0 -393
- package/src/tigerbeetle/src/testing/cluster/message_bus.zig +0 -82
- package/src/tigerbeetle/src/testing/cluster/network.zig +0 -237
- package/src/tigerbeetle/src/testing/cluster/state_checker.zig +0 -169
- package/src/tigerbeetle/src/testing/cluster/storage_checker.zig +0 -202
- package/src/tigerbeetle/src/testing/cluster.zig +0 -443
- package/src/tigerbeetle/src/testing/fuzz.zig +0 -140
- package/src/tigerbeetle/src/testing/hash_log.zig +0 -66
- package/src/tigerbeetle/src/testing/id.zig +0 -99
- package/src/tigerbeetle/src/testing/packet_simulator.zig +0 -364
- package/src/tigerbeetle/src/testing/priority_queue.zig +0 -645
- package/src/tigerbeetle/src/testing/reply_sequence.zig +0 -139
- package/src/tigerbeetle/src/testing/state_machine.zig +0 -249
- package/src/tigerbeetle/src/testing/storage.zig +0 -757
- package/src/tigerbeetle/src/testing/table.zig +0 -247
- package/src/tigerbeetle/src/testing/time.zig +0 -84
- package/src/tigerbeetle/src/tigerbeetle.zig +0 -227
- package/src/tigerbeetle/src/time.zig +0 -112
- package/src/tigerbeetle/src/tracer.zig +0 -529
- package/src/tigerbeetle/src/unit_tests.zig +0 -42
- package/src/tigerbeetle/src/vopr.zig +0 -495
- package/src/tigerbeetle/src/vsr/README.md +0 -209
- package/src/tigerbeetle/src/vsr/client.zig +0 -544
- package/src/tigerbeetle/src/vsr/clock.zig +0 -853
- package/src/tigerbeetle/src/vsr/journal.zig +0 -2413
- package/src/tigerbeetle/src/vsr/journal_format_fuzz.zig +0 -111
- package/src/tigerbeetle/src/vsr/marzullo.zig +0 -309
- package/src/tigerbeetle/src/vsr/replica.zig +0 -6381
- package/src/tigerbeetle/src/vsr/replica_format.zig +0 -219
- package/src/tigerbeetle/src/vsr/superblock.zig +0 -1631
- package/src/tigerbeetle/src/vsr/superblock_client_table.zig +0 -256
- package/src/tigerbeetle/src/vsr/superblock_free_set.zig +0 -929
- package/src/tigerbeetle/src/vsr/superblock_free_set_fuzz.zig +0 -334
- package/src/tigerbeetle/src/vsr/superblock_fuzz.zig +0 -390
- package/src/tigerbeetle/src/vsr/superblock_manifest.zig +0 -615
- package/src/tigerbeetle/src/vsr/superblock_quorums.zig +0 -394
- package/src/tigerbeetle/src/vsr/superblock_quorums_fuzz.zig +0 -314
- package/src/tigerbeetle/src/vsr.zig +0 -1352
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const messages = [
|
|
4
|
-
'prepare',
|
|
5
|
-
'prepare_ok',
|
|
6
|
-
'commit',
|
|
7
|
-
'request_state_transfer',
|
|
8
|
-
'state_transfer',
|
|
9
|
-
'start_view_change',
|
|
10
|
-
'do_view_change',
|
|
11
|
-
'start_view'
|
|
12
|
-
];
|
|
13
|
-
|
|
14
|
-
const views = [
|
|
15
|
-
'old_view',
|
|
16
|
-
'same_view',
|
|
17
|
-
'new_view'
|
|
18
|
-
];
|
|
19
|
-
|
|
20
|
-
const statuses = [
|
|
21
|
-
'normal',
|
|
22
|
-
'view_change',
|
|
23
|
-
'recovering'
|
|
24
|
-
];
|
|
25
|
-
|
|
26
|
-
const tuples = {};
|
|
27
|
-
|
|
28
|
-
statuses.forEach(
|
|
29
|
-
function(status) {
|
|
30
|
-
views.forEach(
|
|
31
|
-
function(view) {
|
|
32
|
-
messages.forEach(
|
|
33
|
-
function(message) {
|
|
34
|
-
tuples[`${message}, ${view}, ${status}`] = true;
|
|
35
|
-
}
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
);
|
|
41
|
-
|
|
42
|
-
Object.keys(tuples).sort().forEach(
|
|
43
|
-
function(key) {
|
|
44
|
-
console.log(key);
|
|
45
|
-
}
|
|
46
|
-
);
|
|
@@ -1,314 +0,0 @@
|
|
|
1
|
-
const std = @import("std");
|
|
2
|
-
const builtin = @import("builtin");
|
|
3
|
-
const assert = std.debug.assert;
|
|
4
|
-
const constants = @import("constants.zig");
|
|
5
|
-
|
|
6
|
-
const log = std.log;
|
|
7
|
-
pub const log_level: std.log.Level = .err;
|
|
8
|
-
|
|
9
|
-
const IO = @import("io.zig").IO;
|
|
10
|
-
|
|
11
|
-
const stdx = @import("stdx.zig");
|
|
12
|
-
const Storage = @import("storage.zig").Storage;
|
|
13
|
-
const MessagePool = @import("message_pool.zig").MessagePool;
|
|
14
|
-
const MessageBus = @import("message_bus.zig").MessageBusClient;
|
|
15
|
-
const StateMachine = @import("state_machine.zig").StateMachineType(Storage, .{
|
|
16
|
-
.message_body_size_max = constants.message_body_size_max,
|
|
17
|
-
});
|
|
18
|
-
const RingBuffer = @import("ring_buffer.zig").RingBuffer;
|
|
19
|
-
|
|
20
|
-
const vsr = @import("vsr.zig");
|
|
21
|
-
const Client = vsr.Client(StateMachine, MessageBus);
|
|
22
|
-
|
|
23
|
-
const tb = @import("tigerbeetle.zig");
|
|
24
|
-
|
|
25
|
-
const batches_count = 1000;
|
|
26
|
-
|
|
27
|
-
const transfers_per_batch: u32 = @divExact(
|
|
28
|
-
constants.message_size_max - @sizeOf(vsr.Header),
|
|
29
|
-
@sizeOf(tb.Transfer),
|
|
30
|
-
);
|
|
31
|
-
comptime {
|
|
32
|
-
assert(transfers_per_batch >= 2041);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const transfers_max: u32 = batches_count * transfers_per_batch;
|
|
36
|
-
|
|
37
|
-
var accounts = [_]tb.Account{
|
|
38
|
-
.{
|
|
39
|
-
.id = 1,
|
|
40
|
-
.user_data = 0,
|
|
41
|
-
.reserved = [_]u8{0} ** 48,
|
|
42
|
-
.ledger = 2,
|
|
43
|
-
.code = 1,
|
|
44
|
-
.flags = .{},
|
|
45
|
-
.debits_pending = 0,
|
|
46
|
-
.debits_posted = 0,
|
|
47
|
-
.credits_pending = 0,
|
|
48
|
-
.credits_posted = 0,
|
|
49
|
-
},
|
|
50
|
-
.{
|
|
51
|
-
.id = 2,
|
|
52
|
-
.user_data = 0,
|
|
53
|
-
.reserved = [_]u8{0} ** 48,
|
|
54
|
-
.ledger = 2,
|
|
55
|
-
.code = 1,
|
|
56
|
-
.flags = .{},
|
|
57
|
-
.debits_pending = 0,
|
|
58
|
-
.debits_posted = 0,
|
|
59
|
-
.credits_pending = 0,
|
|
60
|
-
.credits_posted = 0,
|
|
61
|
-
},
|
|
62
|
-
};
|
|
63
|
-
var create_transfers_latency_max: i64 = 0;
|
|
64
|
-
|
|
65
|
-
pub fn main() !void {
|
|
66
|
-
const stdout = std.io.getStdOut().writer();
|
|
67
|
-
const stderr = std.io.getStdErr().writer();
|
|
68
|
-
|
|
69
|
-
if (builtin.mode != .ReleaseSafe and builtin.mode != .ReleaseFast) {
|
|
70
|
-
try stderr.print("Benchmark must be built as ReleaseSafe for reasonable results.\n", .{});
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
|
74
|
-
defer arena.deinit();
|
|
75
|
-
|
|
76
|
-
const allocator = arena.allocator();
|
|
77
|
-
|
|
78
|
-
const client_id = std.crypto.random.int(u128);
|
|
79
|
-
const cluster_id: u32 = 0;
|
|
80
|
-
var address = [_]std.net.Address{try std.net.Address.parseIp4("127.0.0.1", constants.port)};
|
|
81
|
-
|
|
82
|
-
var io = try IO.init(32, 0);
|
|
83
|
-
defer io.deinit();
|
|
84
|
-
|
|
85
|
-
var message_pool = try MessagePool.init(allocator, .client);
|
|
86
|
-
defer message_pool.deinit(allocator);
|
|
87
|
-
|
|
88
|
-
var client = try Client.init(
|
|
89
|
-
allocator,
|
|
90
|
-
client_id,
|
|
91
|
-
cluster_id,
|
|
92
|
-
@intCast(u8, address.len),
|
|
93
|
-
&message_pool,
|
|
94
|
-
.{
|
|
95
|
-
.configuration = address[0..],
|
|
96
|
-
.io = &io,
|
|
97
|
-
},
|
|
98
|
-
);
|
|
99
|
-
defer client.deinit(allocator);
|
|
100
|
-
|
|
101
|
-
// Pre-allocate a million transfers:
|
|
102
|
-
const transfers = try allocator.alloc(tb.Transfer, transfers_max);
|
|
103
|
-
defer allocator.free(transfers);
|
|
104
|
-
|
|
105
|
-
for (transfers) |*transfer, index| {
|
|
106
|
-
transfer.* = .{
|
|
107
|
-
.id = index + 1,
|
|
108
|
-
.debit_account_id = accounts[0].id,
|
|
109
|
-
.credit_account_id = accounts[1].id,
|
|
110
|
-
.user_data = 0,
|
|
111
|
-
.reserved = 0,
|
|
112
|
-
.pending_id = 0,
|
|
113
|
-
.timeout = 0,
|
|
114
|
-
.ledger = 2,
|
|
115
|
-
.code = 1,
|
|
116
|
-
.flags = .{},
|
|
117
|
-
.amount = 1,
|
|
118
|
-
.timestamp = 0,
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
try wait_for_connect(&client, &io);
|
|
123
|
-
|
|
124
|
-
var queue = TimedQueue.init(&client, &io);
|
|
125
|
-
try queue.push(.{
|
|
126
|
-
.operation = StateMachine.Operation.create_accounts,
|
|
127
|
-
.data = std.mem.sliceAsBytes(accounts[0..]),
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
try queue.execute();
|
|
131
|
-
assert(queue.end != null);
|
|
132
|
-
assert(queue.batches.empty());
|
|
133
|
-
|
|
134
|
-
var count: u64 = 0;
|
|
135
|
-
queue.reset();
|
|
136
|
-
while (count < transfers.len) {
|
|
137
|
-
try queue.push(.{
|
|
138
|
-
.operation = .create_transfers,
|
|
139
|
-
.data = std.mem.sliceAsBytes(transfers[count..][0..transfers_per_batch]),
|
|
140
|
-
});
|
|
141
|
-
count += transfers_per_batch;
|
|
142
|
-
}
|
|
143
|
-
assert(count == transfers_max);
|
|
144
|
-
|
|
145
|
-
try queue.execute();
|
|
146
|
-
assert(queue.end != null);
|
|
147
|
-
assert(queue.batches.empty());
|
|
148
|
-
|
|
149
|
-
var ms = queue.end.? - queue.start.?;
|
|
150
|
-
|
|
151
|
-
const result: i64 = @divFloor(@intCast(i64, transfers.len * 1000), ms);
|
|
152
|
-
try stdout.print("============================================\n", .{});
|
|
153
|
-
try stdout.print("{} batches in {} ms\n", .{ batches_count, ms });
|
|
154
|
-
try stdout.print("{} transfers per second\n", .{result});
|
|
155
|
-
try stdout.print("max p100 latency per {} transfers = {}ms\n", .{
|
|
156
|
-
transfers_per_batch,
|
|
157
|
-
queue.transfers_latency_max,
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
const Batch = struct {
|
|
162
|
-
operation: StateMachine.Operation,
|
|
163
|
-
data: []u8,
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
const TimedQueue = struct {
|
|
167
|
-
batch_start: ?i64,
|
|
168
|
-
start: ?i64,
|
|
169
|
-
end: ?i64,
|
|
170
|
-
transfers_latency_max: i64,
|
|
171
|
-
client: *Client,
|
|
172
|
-
io: *IO,
|
|
173
|
-
batches: RingBuffer(Batch, batches_count, .array),
|
|
174
|
-
|
|
175
|
-
pub fn init(client: *Client, io: *IO) TimedQueue {
|
|
176
|
-
var self = TimedQueue{
|
|
177
|
-
.batch_start = null,
|
|
178
|
-
.start = null,
|
|
179
|
-
.end = null,
|
|
180
|
-
.transfers_latency_max = 0,
|
|
181
|
-
.client = client,
|
|
182
|
-
.io = io,
|
|
183
|
-
.batches = .{},
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
return self;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
pub fn reset(self: *TimedQueue) void {
|
|
190
|
-
self.batch_start = null;
|
|
191
|
-
self.start = null;
|
|
192
|
-
self.end = null;
|
|
193
|
-
self.transfers_latency_max = 0;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
pub fn push(self: *TimedQueue, batch: Batch) !void {
|
|
197
|
-
try self.batches.push(batch);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
pub fn execute(self: *TimedQueue) !void {
|
|
201
|
-
assert(self.start == null);
|
|
202
|
-
assert(!self.batches.empty());
|
|
203
|
-
self.reset();
|
|
204
|
-
log.debug("executing batches...", .{});
|
|
205
|
-
|
|
206
|
-
const now = std.time.milliTimestamp();
|
|
207
|
-
self.start = now;
|
|
208
|
-
if (self.batches.head_ptr()) |starting_batch| {
|
|
209
|
-
log.debug("sending first batch...", .{});
|
|
210
|
-
self.batch_start = now;
|
|
211
|
-
const message = self.client.get_message();
|
|
212
|
-
defer self.client.unref(message);
|
|
213
|
-
|
|
214
|
-
stdx.copy_disjoint(
|
|
215
|
-
.inexact,
|
|
216
|
-
u8,
|
|
217
|
-
message.buffer[@sizeOf(vsr.Header)..],
|
|
218
|
-
std.mem.sliceAsBytes(starting_batch.data),
|
|
219
|
-
);
|
|
220
|
-
self.client.request(
|
|
221
|
-
@intCast(u128, @ptrToInt(self)),
|
|
222
|
-
TimedQueue.lap,
|
|
223
|
-
starting_batch.operation,
|
|
224
|
-
message,
|
|
225
|
-
starting_batch.data.len,
|
|
226
|
-
);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
while (!self.batches.empty()) {
|
|
230
|
-
self.client.tick();
|
|
231
|
-
try self.io.run_for_ns(5 * std.time.ns_per_ms);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
pub fn lap(
|
|
236
|
-
user_data: u128,
|
|
237
|
-
operation: StateMachine.Operation,
|
|
238
|
-
results: Client.Error![]const u8,
|
|
239
|
-
) void {
|
|
240
|
-
const now = std.time.milliTimestamp();
|
|
241
|
-
const value = results catch |err| {
|
|
242
|
-
log.err("Client returned error={o}", .{@errorName(err)});
|
|
243
|
-
@panic("Client returned error during benchmarking.");
|
|
244
|
-
};
|
|
245
|
-
|
|
246
|
-
const self: *TimedQueue = @intToPtr(*TimedQueue, @intCast(usize, user_data));
|
|
247
|
-
const completed_batch: ?Batch = self.batches.pop();
|
|
248
|
-
assert(completed_batch != null);
|
|
249
|
-
assert(completed_batch.?.operation == operation);
|
|
250
|
-
|
|
251
|
-
log.debug("completed batch operation={} start={}", .{
|
|
252
|
-
completed_batch.?.operation,
|
|
253
|
-
self.batch_start,
|
|
254
|
-
});
|
|
255
|
-
const latency = now - self.batch_start.?;
|
|
256
|
-
switch (operation) {
|
|
257
|
-
.create_accounts => {
|
|
258
|
-
const create_accounts_results = std.mem.bytesAsSlice(tb.CreateAccountsResult, value);
|
|
259
|
-
if (create_accounts_results.len > 0) {
|
|
260
|
-
log.err("CreateAccountsResults={any}", .{create_accounts_results});
|
|
261
|
-
@panic("Unexpected result creating accounts.");
|
|
262
|
-
}
|
|
263
|
-
},
|
|
264
|
-
.create_transfers => {
|
|
265
|
-
const create_transfers_results = std.mem.bytesAsSlice(tb.CreateTransfersResult, value);
|
|
266
|
-
if (create_transfers_results.len > 0) {
|
|
267
|
-
log.err("CreateTransfersResults={any}", .{create_transfers_results});
|
|
268
|
-
@panic("Unexpected result creating transfers.");
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
if (latency > self.transfers_latency_max) {
|
|
272
|
-
self.transfers_latency_max = latency;
|
|
273
|
-
}
|
|
274
|
-
},
|
|
275
|
-
else => unreachable,
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
if (self.batches.head_ptr()) |next_batch| {
|
|
279
|
-
const message = self.client.get_message();
|
|
280
|
-
defer self.client.unref(message);
|
|
281
|
-
|
|
282
|
-
stdx.copy_disjoint(
|
|
283
|
-
.inexact,
|
|
284
|
-
u8,
|
|
285
|
-
message.buffer[@sizeOf(vsr.Header)..],
|
|
286
|
-
std.mem.sliceAsBytes(next_batch.data),
|
|
287
|
-
);
|
|
288
|
-
|
|
289
|
-
self.batch_start = std.time.milliTimestamp();
|
|
290
|
-
self.client.request(
|
|
291
|
-
@intCast(u128, @ptrToInt(self)),
|
|
292
|
-
TimedQueue.lap,
|
|
293
|
-
next_batch.operation,
|
|
294
|
-
message,
|
|
295
|
-
next_batch.data.len,
|
|
296
|
-
);
|
|
297
|
-
} else {
|
|
298
|
-
log.debug("stopping timer...", .{});
|
|
299
|
-
self.end = now;
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
};
|
|
303
|
-
|
|
304
|
-
fn wait_for_connect(client: *Client, io: *IO) !void {
|
|
305
|
-
var ticks: u32 = 0;
|
|
306
|
-
while (ticks < 20) : (ticks += 1) {
|
|
307
|
-
client.tick();
|
|
308
|
-
// We tick IO outside of client so that an IO instance can be shared by multiple clients:
|
|
309
|
-
// Otherwise we will hit io_uring memory restrictions too quickly.
|
|
310
|
-
try io.tick();
|
|
311
|
-
|
|
312
|
-
std.time.sleep(10 * std.time.ns_per_ms);
|
|
313
|
-
}
|
|
314
|
-
}
|
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
//! Raw configuration values.
|
|
2
|
-
//!
|
|
3
|
-
//! Code which needs these values should use `constants.zig` instead.
|
|
4
|
-
//! Configuration values are set from a combination of:
|
|
5
|
-
//! - default values
|
|
6
|
-
//! - `root.tigerbeetle_config`
|
|
7
|
-
//! - `@import("tigerbeetle_options")`
|
|
8
|
-
|
|
9
|
-
const builtin = @import("builtin");
|
|
10
|
-
const std = @import("std");
|
|
11
|
-
|
|
12
|
-
const root = @import("root");
|
|
13
|
-
// Allow setting build-time config either via `build.zig` `Options`, or via a struct in the root file.
|
|
14
|
-
const build_options =
|
|
15
|
-
if (@hasDecl(root, "vsr_options")) root.vsr_options else @import("vsr_options");
|
|
16
|
-
|
|
17
|
-
const vsr = @import("vsr.zig");
|
|
18
|
-
const sector_size = @import("constants.zig").sector_size;
|
|
19
|
-
|
|
20
|
-
pub const Config = struct {
|
|
21
|
-
pub const Cluster = ConfigCluster;
|
|
22
|
-
pub const Process = ConfigProcess;
|
|
23
|
-
|
|
24
|
-
cluster: ConfigCluster,
|
|
25
|
-
process: ConfigProcess,
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
/// Configurations which are tunable per-replica (or per-client).
|
|
29
|
-
/// - Replica configs need not equal each other.
|
|
30
|
-
/// - Client configs need not equal each other.
|
|
31
|
-
/// - Client configs need not equal replica configs.
|
|
32
|
-
/// - Replica configs can change between restarts.
|
|
33
|
-
///
|
|
34
|
-
/// Fields are documented within constants.zig.
|
|
35
|
-
const ConfigProcess = struct {
|
|
36
|
-
log_level: std.log.Level = .info,
|
|
37
|
-
tracer_backend: TracerBackend = .none,
|
|
38
|
-
hash_log_mode: HashLogMode = .none,
|
|
39
|
-
verify: bool,
|
|
40
|
-
port: u16 = 3001,
|
|
41
|
-
address: []const u8 = "127.0.0.1",
|
|
42
|
-
memory_size_max_default: u64 = 1024 * 1024 * 1024,
|
|
43
|
-
cache_accounts_max: usize,
|
|
44
|
-
cache_transfers_max: usize,
|
|
45
|
-
cache_transfers_posted_max: usize,
|
|
46
|
-
client_request_queue_max: usize = 32,
|
|
47
|
-
lsm_manifest_node_size: usize = 16 * 1024,
|
|
48
|
-
connection_delay_min_ms: u64 = 50,
|
|
49
|
-
connection_delay_max_ms: u64 = 1000,
|
|
50
|
-
tcp_backlog: u31 = 64,
|
|
51
|
-
tcp_rcvbuf: c_int = 4 * 1024 * 1024,
|
|
52
|
-
tcp_keepalive: bool = true,
|
|
53
|
-
tcp_keepidle: c_int = 5,
|
|
54
|
-
tcp_keepintvl: c_int = 4,
|
|
55
|
-
tcp_keepcnt: c_int = 3,
|
|
56
|
-
tcp_nodelay: bool = true,
|
|
57
|
-
direct_io: bool,
|
|
58
|
-
direct_io_required: bool,
|
|
59
|
-
journal_iops_read_max: usize = 8,
|
|
60
|
-
journal_iops_write_max: usize = 8,
|
|
61
|
-
tick_ms: u63 = 10,
|
|
62
|
-
rtt_ms: u64 = 300,
|
|
63
|
-
rtt_multiple: u8 = 2,
|
|
64
|
-
backoff_min_ms: u64 = 100,
|
|
65
|
-
backoff_max_ms: u64 = 10000,
|
|
66
|
-
clock_offset_tolerance_max_ms: u64 = 10000,
|
|
67
|
-
clock_epoch_max_ms: u64 = 60000,
|
|
68
|
-
clock_synchronization_window_min_ms: u64 = 2000,
|
|
69
|
-
clock_synchronization_window_max_ms: u64 = 20000,
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
/// Configurations which are tunable per-cluster.
|
|
73
|
-
/// - All replicas within a cluster must have the same configuration.
|
|
74
|
-
/// - Replicas must reuse the same configuration when the binary is upgraded — they do not change
|
|
75
|
-
/// over the cluster lifetime.
|
|
76
|
-
/// - The storage formats generated by different ConfigClusters are incompatible.
|
|
77
|
-
///
|
|
78
|
-
/// Fields are documented within constants.zig.
|
|
79
|
-
const ConfigCluster = struct {
|
|
80
|
-
cache_line_size: comptime_int = 64,
|
|
81
|
-
clients_max: usize,
|
|
82
|
-
pipeline_prepare_queue_max: usize = 8,
|
|
83
|
-
view_change_headers_max: usize = 8,
|
|
84
|
-
quorum_replication_max: u8 = 3,
|
|
85
|
-
journal_slot_count: usize = 1024,
|
|
86
|
-
message_size_max: usize = 1 * 1024 * 1024,
|
|
87
|
-
superblock_copies: comptime_int = 4,
|
|
88
|
-
storage_size_max: u64 = 16 * 1024 * 1024 * 1024 * 1024,
|
|
89
|
-
block_size: comptime_int = 64 * 1024,
|
|
90
|
-
lsm_levels: u7 = 7,
|
|
91
|
-
lsm_growth_factor: u32 = 8,
|
|
92
|
-
lsm_table_size_max: usize = 64 * 1024 * 1024,
|
|
93
|
-
lsm_batch_multiple: comptime_int = 4,
|
|
94
|
-
lsm_snapshots_max: usize = 32,
|
|
95
|
-
lsm_value_to_key_layout_ratio_min: comptime_int = 16,
|
|
96
|
-
|
|
97
|
-
/// The WAL requires at least two sectors of redundant headers — otherwise we could lose them all to
|
|
98
|
-
/// a single torn write. A replica needs at least one valid redundant header to determine an
|
|
99
|
-
/// (untrusted) maximum op in recover_torn_prepare(), without which it cannot truncate a torn
|
|
100
|
-
/// prepare.
|
|
101
|
-
pub const journal_slot_count_min = 2 * @divExact(sector_size, @sizeOf(vsr.Header));
|
|
102
|
-
|
|
103
|
-
pub const clients_max_min = 1;
|
|
104
|
-
|
|
105
|
-
/// The smallest possible message_size_max (for use in the simulator to improve performance).
|
|
106
|
-
/// The message body must have room for pipeline_prepare_queue_max headers in the DVC.
|
|
107
|
-
pub fn message_size_max_min(clients_max: usize) usize {
|
|
108
|
-
return std.math.max(
|
|
109
|
-
sector_size,
|
|
110
|
-
std.mem.alignForward(
|
|
111
|
-
@sizeOf(vsr.Header) + clients_max * @sizeOf(vsr.Header),
|
|
112
|
-
sector_size,
|
|
113
|
-
),
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
pub const ConfigBase = enum {
|
|
119
|
-
production,
|
|
120
|
-
development,
|
|
121
|
-
test_min,
|
|
122
|
-
default,
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
pub const TracerBackend = enum {
|
|
126
|
-
none,
|
|
127
|
-
// Writes to a file (./tracer.json) which can be uploaded to https://ui.perfetto.dev/
|
|
128
|
-
perfetto,
|
|
129
|
-
// Sends data to https://github.com/wolfpld/tracy.
|
|
130
|
-
tracy,
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
pub const HashLogMode = enum {
|
|
134
|
-
none,
|
|
135
|
-
create,
|
|
136
|
-
check,
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
pub const configs = struct {
|
|
140
|
-
/// A good default config for production.
|
|
141
|
-
pub const default_production = Config{
|
|
142
|
-
.process = .{
|
|
143
|
-
.direct_io = true,
|
|
144
|
-
.direct_io_required = true,
|
|
145
|
-
.cache_accounts_max = 1024 * 1024,
|
|
146
|
-
.cache_transfers_max = 0,
|
|
147
|
-
.cache_transfers_posted_max = 256 * 1024,
|
|
148
|
-
.verify = false,
|
|
149
|
-
},
|
|
150
|
-
.cluster = .{
|
|
151
|
-
.clients_max = 32,
|
|
152
|
-
},
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
/// A good default config for local development.
|
|
156
|
-
/// (For production, use default_production instead.)
|
|
157
|
-
/// The cluster-config is compatible with the default production config.
|
|
158
|
-
pub const default_development = Config{
|
|
159
|
-
.process = .{
|
|
160
|
-
.direct_io = true,
|
|
161
|
-
.direct_io_required = false,
|
|
162
|
-
.cache_accounts_max = 1024 * 1024,
|
|
163
|
-
.cache_transfers_max = 0,
|
|
164
|
-
.cache_transfers_posted_max = 256 * 1024,
|
|
165
|
-
.verify = true,
|
|
166
|
-
},
|
|
167
|
-
.cluster = default_production.cluster,
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
/// Minimal test configuration — small WAL, small grid block size, etc.
|
|
171
|
-
/// Not suitable for production, but good for testing code that would be otherwise hard to reach.
|
|
172
|
-
pub const test_min = Config{
|
|
173
|
-
.process = .{
|
|
174
|
-
.direct_io = false,
|
|
175
|
-
.direct_io_required = false,
|
|
176
|
-
.cache_accounts_max = 2048,
|
|
177
|
-
.cache_transfers_max = 0,
|
|
178
|
-
.cache_transfers_posted_max = 2048,
|
|
179
|
-
.verify = true,
|
|
180
|
-
},
|
|
181
|
-
.cluster = .{
|
|
182
|
-
.clients_max = 4 + 3,
|
|
183
|
-
.pipeline_prepare_queue_max = 4,
|
|
184
|
-
.view_change_headers_max = 4,
|
|
185
|
-
.journal_slot_count = Config.Cluster.journal_slot_count_min,
|
|
186
|
-
.message_size_max = Config.Cluster.message_size_max_min(4),
|
|
187
|
-
.storage_size_max = 4 * 1024 * 1024 * 1024,
|
|
188
|
-
|
|
189
|
-
.block_size = sector_size,
|
|
190
|
-
.lsm_growth_factor = 4,
|
|
191
|
-
.lsm_table_size_max = 64 * 1024,
|
|
192
|
-
},
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
const default = if (@hasDecl(root, "tigerbeetle_config"))
|
|
196
|
-
root.tigerbeetle_config
|
|
197
|
-
else if (builtin.is_test)
|
|
198
|
-
test_min
|
|
199
|
-
else
|
|
200
|
-
default_development;
|
|
201
|
-
|
|
202
|
-
pub const current = current: {
|
|
203
|
-
var base = if (@hasDecl(root, "decode_events"))
|
|
204
|
-
// TODO(DJ) This is a hack to work around the absense of tigerbeetle_build_options.
|
|
205
|
-
// This should be removed once the node client is built using `zig build`.
|
|
206
|
-
default_development
|
|
207
|
-
else switch (build_options.config_base) {
|
|
208
|
-
.default => default,
|
|
209
|
-
.production => default_production,
|
|
210
|
-
.development => default_development,
|
|
211
|
-
.test_min => test_min,
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
// TODO Use additional build options to overwrite other fields.
|
|
215
|
-
base.process.tracer_backend = if (@hasDecl(root, "tracer_backend"))
|
|
216
|
-
// TODO(jamii)
|
|
217
|
-
// This branch is a hack used to work around the absence of tigerbeetle_build_options.
|
|
218
|
-
// This should be removed once the node client is built using `zig build`.
|
|
219
|
-
root.tracer_backend
|
|
220
|
-
else
|
|
221
|
-
// Zig's `addOptions` reuses the type, but redeclares it — identical structurally,
|
|
222
|
-
// but a different type from a nominal typing perspective.
|
|
223
|
-
@intToEnum(TracerBackend, @enumToInt(build_options.tracer_backend));
|
|
224
|
-
|
|
225
|
-
base.process.hash_log_mode = if (@hasDecl(root, "decode_events"))
|
|
226
|
-
// TODO(DJ) This is a hack to work around the absense of tigerbeetle_build_options.
|
|
227
|
-
// This should be removed once the node client is built using `zig build`.
|
|
228
|
-
.none
|
|
229
|
-
else
|
|
230
|
-
@intToEnum(HashLogMode, @enumToInt(build_options.hash_log_mode));
|
|
231
|
-
|
|
232
|
-
break :current base;
|
|
233
|
-
};
|
|
234
|
-
};
|