tigerbeetle-node 0.3.3 → 0.5.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 +21 -7
- package/dist/benchmark.js +1 -1
- package/dist/benchmark.js.map +1 -1
- package/dist/index.d.ts +22 -20
- package/dist/index.js +40 -18
- package/dist/index.js.map +1 -1
- package/dist/test.js +13 -1
- package/dist/test.js.map +1 -1
- package/package.json +12 -12
- package/scripts/postinstall.sh +2 -2
- package/src/benchmark.ts +4 -4
- package/src/index.ts +35 -9
- package/src/node.zig +139 -28
- package/src/test.ts +19 -5
- package/src/tigerbeetle/scripts/benchmark.sh +10 -3
- package/src/tigerbeetle/scripts/install.sh +2 -2
- package/src/tigerbeetle/scripts/install_zig.bat +109 -0
- package/src/tigerbeetle/scripts/install_zig.sh +21 -4
- package/src/tigerbeetle/scripts/vopr.bat +48 -0
- package/src/tigerbeetle/scripts/vopr.sh +33 -0
- package/src/tigerbeetle/src/benchmark.zig +74 -42
- package/src/tigerbeetle/src/cli.zig +136 -83
- package/src/tigerbeetle/src/config.zig +80 -26
- package/src/tigerbeetle/src/demo.zig +101 -78
- package/src/tigerbeetle/src/demo_01_create_accounts.zig +2 -7
- package/src/tigerbeetle/src/demo_02_lookup_accounts.zig +2 -7
- package/src/tigerbeetle/src/demo_03_create_transfers.zig +2 -7
- package/src/tigerbeetle/src/demo_04_create_transfers_two_phase_commit.zig +2 -5
- package/src/tigerbeetle/src/demo_05_accept_transfers.zig +2 -7
- package/src/tigerbeetle/src/demo_06_reject_transfers.zig +2 -7
- package/src/tigerbeetle/src/demo_07_lookup_transfers.zig +8 -0
- package/src/tigerbeetle/src/fifo.zig +20 -11
- package/src/tigerbeetle/src/io.zig +35 -22
- package/src/tigerbeetle/src/io_darwin.zig +701 -0
- package/src/tigerbeetle/src/main.zig +72 -25
- package/src/tigerbeetle/src/message_bus.zig +379 -456
- package/src/tigerbeetle/src/message_pool.zig +3 -3
- package/src/tigerbeetle/src/ring_buffer.zig +192 -37
- package/src/tigerbeetle/src/simulator.zig +317 -0
- package/src/tigerbeetle/src/state_machine.zig +846 -38
- package/src/tigerbeetle/src/storage.zig +488 -90
- package/src/tigerbeetle/src/test/cluster.zig +221 -0
- package/src/tigerbeetle/src/test/message_bus.zig +92 -0
- package/src/tigerbeetle/src/test/network.zig +182 -0
- package/src/tigerbeetle/src/test/packet_simulator.zig +371 -0
- package/src/tigerbeetle/src/test/state_checker.zig +142 -0
- package/src/tigerbeetle/src/test/state_machine.zig +71 -0
- package/src/tigerbeetle/src/test/storage.zig +375 -0
- package/src/tigerbeetle/src/test/time.zig +84 -0
- package/src/tigerbeetle/src/tigerbeetle.zig +6 -3
- package/src/tigerbeetle/src/time.zig +65 -0
- package/src/tigerbeetle/src/unit_tests.zig +14 -0
- package/src/tigerbeetle/src/vsr/client.zig +519 -0
- package/src/tigerbeetle/src/vsr/clock.zig +829 -0
- package/src/tigerbeetle/src/vsr/journal.zig +1368 -0
- package/src/tigerbeetle/src/vsr/marzullo.zig +306 -0
- package/src/tigerbeetle/src/vsr/replica.zig +4248 -0
- package/src/tigerbeetle/src/vsr.zig +601 -0
- package/src/tigerbeetle/LICENSE +0 -177
- package/src/tigerbeetle/README.md +0 -116
- package/src/tigerbeetle/src/client.zig +0 -319
- package/src/tigerbeetle/src/concurrent_ranges.zig +0 -162
- package/src/tigerbeetle/src/fixed_array_list.zig +0 -53
- package/src/tigerbeetle/src/io_async.zig +0 -600
- package/src/tigerbeetle/src/journal.zig +0 -567
- package/src/tigerbeetle/src/test_client.zig +0 -41
- package/src/tigerbeetle/src/test_main.zig +0 -118
- package/src/tigerbeetle/src/test_message_bus.zig +0 -132
- package/src/tigerbeetle/src/vr/journal.zig +0 -672
- package/src/tigerbeetle/src/vr/replica.zig +0 -3061
- package/src/tigerbeetle/src/vr.zig +0 -374
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
@echo off
|
|
2
|
+
|
|
3
|
+
set DEFAULT_RELEASE=0.8.1
|
|
4
|
+
|
|
5
|
+
:: Determine the Zig build:
|
|
6
|
+
if "%~1"=="" (
|
|
7
|
+
set ZIG_RELEASE=%DEFAULT_RELEASE%
|
|
8
|
+
) else if "%~1"=="latest" (
|
|
9
|
+
set ZIG_RELEASE=builds
|
|
10
|
+
) else (
|
|
11
|
+
set ZIG_RELEASE=%~1
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
:: Checks format of release version.
|
|
15
|
+
echo.%ZIG_RELEASE% | findstr /b /r /c:"builds" /c:"^[0-9][0-9]*.[0-9][0-9]*.[0-9][0-9]*">nul || (echo.Unexpected release format. && exit 1)
|
|
16
|
+
|
|
17
|
+
set ZIG_OS=windows
|
|
18
|
+
set ZIG_ARCH=x86_64
|
|
19
|
+
|
|
20
|
+
set ZIG_TARGET=zig-%ZIG_OS%-%ZIG_ARCH%
|
|
21
|
+
|
|
22
|
+
:: Determine the build, split the JSON line on whitespace and extract the 2nd field:
|
|
23
|
+
for /f "tokens=2" %%a in ('curl --silent https://ziglang.org/download/index.json ^| findstr %ZIG_TARGET% ^| findstr %ZIG_RELEASE%' ) do (
|
|
24
|
+
set ZIG_URL=%%a
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
:: Then remove quotes and commas:
|
|
28
|
+
for /f %%b in ("%ZIG_URL:,=%") do (
|
|
29
|
+
set ZIG_URL=%%~b
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
:: Checks the ZIG_URL variable follows the expected format.
|
|
33
|
+
echo.%ZIG_URL% | findstr /b /r /c:"https://ziglang.org/builds/" /c:"https://ziglang.org/download/%ZIG_RELEASE%">nul || (echo.Unexpected release URL format. && exit 1)
|
|
34
|
+
|
|
35
|
+
if "%ZIG_RELEASE%"=="builds" (
|
|
36
|
+
echo Installing Zig latest build...
|
|
37
|
+
) else (
|
|
38
|
+
echo Installing Zig %ZIG_RELEASE% release build...
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
:: Using variable modifiers to determine the directory and filename from the URL:
|
|
42
|
+
:: %~ni Expands %i to a file name only and %~xi Expands %i to a file name extension only.
|
|
43
|
+
for /f %%i in ("%ZIG_URL%") do (
|
|
44
|
+
set ZIG_DIRECTORY=%%~ni
|
|
45
|
+
set ZIG_TARBALL=%%~nxi
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
:: Checks the ZIG_DIRECTORY variable follows the expected format.
|
|
49
|
+
echo.%ZIG_DIRECTORY% | findstr /b /r /c:"zig-win64-" /c:"zig-windows-x86_64-">nul || (echo.Unexpected zip directory name format. && exit 1)
|
|
50
|
+
|
|
51
|
+
:: Making sure we download to the same output document, without wget adding "-1" etc. if the file was previously partially downloaded:
|
|
52
|
+
if exist %ZIG_TARBALL% (
|
|
53
|
+
del /q %ZIG_TARBALL%
|
|
54
|
+
if exist %ZIG_TARBALL% (
|
|
55
|
+
echo Failed to delete %ZIG_TARBALL%.
|
|
56
|
+
exit 1
|
|
57
|
+
)
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
echo Downloading %ZIG_URL%...
|
|
61
|
+
curl --silent --progress-bar --output %ZIG_TARBALL% %ZIG_URL%
|
|
62
|
+
if not exist %ZIG_TARBALL% (
|
|
63
|
+
echo Failed to download Zig zip file.
|
|
64
|
+
exit 1
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
:: Replace any existing Zig installation so that we can install or upgrade:
|
|
68
|
+
echo Removing any existing 'zig' and %ZIG_DIRECTORY% folders before extracting.
|
|
69
|
+
if exist zig\ (
|
|
70
|
+
rd /s /q zig\
|
|
71
|
+
:: Ensure the directory has been deleted.
|
|
72
|
+
if exist zig\ (
|
|
73
|
+
echo The ‘zig’ directory could not be deleted.
|
|
74
|
+
exit 1
|
|
75
|
+
)
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
if exist %ZIG_DIRECTORY%\ (
|
|
79
|
+
rd /s /q %ZIG_DIRECTORY%
|
|
80
|
+
:: Ensure the directory has been deleted.
|
|
81
|
+
if exist %ZIG_DIRECTORY% (
|
|
82
|
+
echo The %ZIG_DIRECTORY% directory could not be deleted.
|
|
83
|
+
exit 1
|
|
84
|
+
)
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
:: Extract and then remove the downloaded tarball:
|
|
88
|
+
echo Extracting %ZIG_TARBALL%...
|
|
89
|
+
powershell -Command "Expand-Archive %ZIG_TARBALL% -DestinationPath ."
|
|
90
|
+
if not exist %ZIG_TARBALL% (
|
|
91
|
+
echo Failed to extract zip file.
|
|
92
|
+
exit 1
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
echo Installing %ZIG_DIRECTORY% to 'zig' in current working directory...
|
|
96
|
+
ren %ZIG_DIRECTORY% zig
|
|
97
|
+
if exist %ZIG_DIRECTORY% (
|
|
98
|
+
echo Failed to rename %ZIG_DIRECTORY% to zig.
|
|
99
|
+
exit 1
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
:: Removes the zip file
|
|
103
|
+
del /q %ZIG_TARBALL%
|
|
104
|
+
if exist %ZIG_TARBALL% (
|
|
105
|
+
echo Failed to delete %ZIG_TARBALL% file.
|
|
106
|
+
exit 1
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
echo "Congratulations, you have successfully installed Zig version %ZIG_RELEASE%. Enjoy!"
|
|
@@ -1,12 +1,23 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
set -e
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
# Default to the 0.8.1 build, or allow the latest dev build, or an explicit release version:
|
|
5
|
+
if [ -z "$1" ]; then
|
|
6
|
+
ZIG_RELEASE="0.8.1"
|
|
7
|
+
elif [ "$1" == "latest" ]; then
|
|
8
8
|
ZIG_RELEASE="builds"
|
|
9
|
+
else
|
|
10
|
+
ZIG_RELEASE=$1
|
|
11
|
+
fi
|
|
12
|
+
|
|
13
|
+
# Validate the release version explicitly:
|
|
14
|
+
if [[ $ZIG_RELEASE =~ ^builds$ ]]; then
|
|
9
15
|
echo "Installing Zig latest build..."
|
|
16
|
+
elif [[ $ZIG_RELEASE =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
17
|
+
echo "Installing Zig $ZIG_RELEASE release build..."
|
|
18
|
+
else
|
|
19
|
+
echo "Release version invalid"
|
|
20
|
+
exit 1
|
|
10
21
|
fi
|
|
11
22
|
|
|
12
23
|
# Determine the architecture:
|
|
@@ -32,6 +43,12 @@ else
|
|
|
32
43
|
ZIG_URL=`curl --silent https://ziglang.org/download/index.json | grep "$ZIG_TARGET" | grep "$ZIG_RELEASE" | awk '{print $2}' | sed 's/[",]//g'`
|
|
33
44
|
fi
|
|
34
45
|
|
|
46
|
+
# Ensure that the release is actually hosted on the ziglang.org website:
|
|
47
|
+
if [ -z "$ZIG_URL" ]; then
|
|
48
|
+
echo "Release not found on ziglang.org"
|
|
49
|
+
exit 1
|
|
50
|
+
fi
|
|
51
|
+
|
|
35
52
|
# Work out the filename from the URL, as well as the directory without the ".tar.xz" file extension:
|
|
36
53
|
ZIG_TARBALL=`basename "$ZIG_URL"`
|
|
37
54
|
ZIG_DIRECTORY=`basename "$ZIG_TARBALL" .tar.xz`
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
:: Installs Zig if needed and runs the VOPR
|
|
2
|
+
@echo off
|
|
3
|
+
|
|
4
|
+
:: Install Zig if a zig folder does not already exist:
|
|
5
|
+
if not exist zig\ (
|
|
6
|
+
:: Installs the latest version of Zig
|
|
7
|
+
call scripts\install_zig.bat
|
|
8
|
+
:: Checks that the Zig folder now exists
|
|
9
|
+
if not exist zig\ (
|
|
10
|
+
echo The Zig installation failed.
|
|
11
|
+
exit 1
|
|
12
|
+
)
|
|
13
|
+
echo Running the TigerBeetle VOPR for the first time...
|
|
14
|
+
echo Visit https://www.tigerbeetle.com
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
:: If a seed is provided as an argument then replay the seed, otherwise test 1,000 seeds:
|
|
18
|
+
if not "%~1"=="" (
|
|
19
|
+
:: Build in fast ReleaseSafe mode if required, useful where you don't need debug logging:
|
|
20
|
+
if "%~2"=="-OReleaseSafe" (
|
|
21
|
+
echo Replaying seed %~1 in ReleaseSafe mode...
|
|
22
|
+
call zig\zig run src\simulator.zig -OReleaseSafe -- %~1
|
|
23
|
+
if not %ERRORLEVEL%==0 (
|
|
24
|
+
echo Cannot replay the %~1 seed using the VOPR.
|
|
25
|
+
exit 1
|
|
26
|
+
)
|
|
27
|
+
) else (
|
|
28
|
+
echo Replaying seed %~1 in Debug mode with full debug logging enabled...
|
|
29
|
+
call zig\zig run src\simulator.zig -ODebug -- %~1
|
|
30
|
+
if not %ERRORLEVEL%==0 (
|
|
31
|
+
echo Cannot run the VOPR.
|
|
32
|
+
exit 1
|
|
33
|
+
)
|
|
34
|
+
)
|
|
35
|
+
) else (
|
|
36
|
+
call zig\zig build-exe src\simulator.zig -OReleaseSafe
|
|
37
|
+
if not %ERRORLEVEL%==0 (
|
|
38
|
+
echo Cannot run the VOPR.
|
|
39
|
+
exit 1
|
|
40
|
+
)
|
|
41
|
+
for %%i in (1,1,1000) do (
|
|
42
|
+
call simulator
|
|
43
|
+
if not %ERRORLEVEL%==0 (
|
|
44
|
+
echo Cannot run a seed using the VOPR.
|
|
45
|
+
exit 1
|
|
46
|
+
)
|
|
47
|
+
)
|
|
48
|
+
)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -e
|
|
3
|
+
|
|
4
|
+
# Install Zig 0.8.0 if it does not already exist:
|
|
5
|
+
if [ ! -d "zig" ]; then
|
|
6
|
+
scripts/install_zig.sh 0.8.0
|
|
7
|
+
echo ""
|
|
8
|
+
echo "Running the TigerBeetle VOPR for the first time..."
|
|
9
|
+
echo "Visit https://www.tigerbeetle.com"
|
|
10
|
+
sleep 2
|
|
11
|
+
fi
|
|
12
|
+
|
|
13
|
+
# If a seed is provided as an argument then replay the seed, otherwise test a 1,000 seeds:
|
|
14
|
+
if [ "$1" ]; then
|
|
15
|
+
|
|
16
|
+
# Build in fast ReleaseSafe mode if required, useful where you don't need debug logging:
|
|
17
|
+
if [ "$2" == "-OReleaseSafe" ]; then
|
|
18
|
+
echo "Replaying seed $1 in ReleaseSafe mode..."
|
|
19
|
+
BUILD_MODE="-OReleaseSafe"
|
|
20
|
+
else
|
|
21
|
+
echo "Replaying seed $1 in Debug mode with full debug logging enabled..."
|
|
22
|
+
BUILD_MODE="-ODebug"
|
|
23
|
+
fi
|
|
24
|
+
echo ""
|
|
25
|
+
|
|
26
|
+
zig/zig run src/simulator.zig $BUILD_MODE -- $1
|
|
27
|
+
else
|
|
28
|
+
zig/zig build-exe src/simulator.zig -OReleaseSafe
|
|
29
|
+
for I in {1..1000}
|
|
30
|
+
do
|
|
31
|
+
./simulator
|
|
32
|
+
done
|
|
33
|
+
fi
|
|
@@ -4,20 +4,25 @@ const config = @import("config.zig");
|
|
|
4
4
|
|
|
5
5
|
const cli = @import("cli.zig");
|
|
6
6
|
const IO = @import("io.zig").IO;
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
const MessageBus = @import("message_bus.zig").MessageBusClient;
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const Commit = TigerBeetle.Commit;
|
|
12
|
-
const Account = TigerBeetle.Account;
|
|
13
|
-
const CreateAccountsResult = TigerBeetle.CreateAccountsResult;
|
|
14
|
-
const CreateTransfersResult = TigerBeetle.CreateTransfersResult;
|
|
15
|
-
const Operation = @import("state_machine.zig").Operation;
|
|
16
|
-
const Header = @import("vr.zig").Header;
|
|
9
|
+
const StateMachine = @import("state_machine.zig").StateMachine;
|
|
10
|
+
const Operation = StateMachine.Operation;
|
|
17
11
|
const RingBuffer = @import("ring_buffer.zig").RingBuffer;
|
|
18
12
|
|
|
13
|
+
const vsr = @import("vsr.zig");
|
|
14
|
+
const Header = vsr.Header;
|
|
15
|
+
const Client = vsr.Client(StateMachine, MessageBus);
|
|
16
|
+
|
|
17
|
+
const tb = @import("tigerbeetle.zig");
|
|
18
|
+
const Transfer = tb.Transfer;
|
|
19
|
+
const Commit = tb.Commit;
|
|
20
|
+
const Account = tb.Account;
|
|
21
|
+
const CreateAccountsResult = tb.CreateAccountsResult;
|
|
22
|
+
const CreateTransfersResult = tb.CreateTransfersResult;
|
|
23
|
+
|
|
19
24
|
const MAX_TRANSFERS: u32 = 1_000_000;
|
|
20
|
-
const BATCH_SIZE: u32 =
|
|
25
|
+
const BATCH_SIZE: u32 = 5_000;
|
|
21
26
|
const IS_TWO_PHASE_COMMIT = false;
|
|
22
27
|
const BENCHMARK = if (IS_TWO_PHASE_COMMIT) 500_000 else 1_000_000;
|
|
23
28
|
const RESULT_TOLERANCE = 10; // percent
|
|
@@ -25,7 +30,7 @@ const BATCHES: f32 = MAX_TRANSFERS / BATCH_SIZE;
|
|
|
25
30
|
const TOTAL_BATCHES = @ceil(BATCHES);
|
|
26
31
|
|
|
27
32
|
const log = std.log;
|
|
28
|
-
pub const log_level: std.log.Level = .
|
|
33
|
+
pub const log_level: std.log.Level = .notice;
|
|
29
34
|
|
|
30
35
|
var accounts = [_]Account{
|
|
31
36
|
Account{
|
|
@@ -57,28 +62,32 @@ var max_create_transfers_latency: i64 = 0;
|
|
|
57
62
|
var max_commit_transfers_latency: i64 = 0;
|
|
58
63
|
|
|
59
64
|
pub fn main() !void {
|
|
60
|
-
|
|
65
|
+
const stdout = std.io.getStdOut().writer();
|
|
66
|
+
const stderr = std.io.getStdErr().writer();
|
|
67
|
+
|
|
61
68
|
if (std.builtin.mode != .ReleaseSafe and std.builtin.mode != .ReleaseFast) {
|
|
62
|
-
|
|
69
|
+
try stderr.print("Benchmark must be built as ReleaseSafe for minimum performance.\n", .{});
|
|
63
70
|
}
|
|
71
|
+
|
|
64
72
|
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
|
65
73
|
defer arena.deinit();
|
|
66
74
|
const allocator = &arena.allocator;
|
|
67
75
|
|
|
68
|
-
const client_id
|
|
69
|
-
const cluster_id:
|
|
76
|
+
const client_id = std.crypto.random.int(u128);
|
|
77
|
+
const cluster_id: u32 = 0;
|
|
70
78
|
var address = [_]std.net.Address{try std.net.Address.parseIp4("127.0.0.1", config.port)};
|
|
71
79
|
var io = try IO.init(32, 0);
|
|
72
80
|
var message_bus = try MessageBus.init(allocator, cluster_id, address[0..], client_id, &io);
|
|
73
81
|
defer message_bus.deinit();
|
|
74
82
|
var client = try Client.init(
|
|
75
83
|
allocator,
|
|
84
|
+
client_id,
|
|
76
85
|
cluster_id,
|
|
77
|
-
@intCast(
|
|
86
|
+
@intCast(u8, address.len),
|
|
78
87
|
&message_bus,
|
|
79
88
|
);
|
|
80
89
|
defer client.deinit();
|
|
81
|
-
message_bus.
|
|
90
|
+
message_bus.set_on_message(*Client, &client, Client.on_message);
|
|
82
91
|
|
|
83
92
|
// Pre-allocate a million transfers:
|
|
84
93
|
var transfers = try arena.allocator.alloc(Transfer, MAX_TRANSFERS);
|
|
@@ -111,7 +120,7 @@ pub fn main() !void {
|
|
|
111
120
|
|
|
112
121
|
try wait_for_connect(&client, &io);
|
|
113
122
|
|
|
114
|
-
|
|
123
|
+
try stdout.print("creating accounts...\n", .{});
|
|
115
124
|
var queue = TimedQueue.init(&client, &io);
|
|
116
125
|
try queue.push(.{
|
|
117
126
|
.operation = Operation.create_accounts,
|
|
@@ -121,7 +130,7 @@ pub fn main() !void {
|
|
|
121
130
|
assert(queue.end != null);
|
|
122
131
|
assert(queue.batches.empty());
|
|
123
132
|
|
|
124
|
-
|
|
133
|
+
try stdout.print("batching transfers...\n", .{});
|
|
125
134
|
var count: u64 = 0;
|
|
126
135
|
queue.reset();
|
|
127
136
|
while (count < transfers.len) {
|
|
@@ -141,29 +150,27 @@ pub fn main() !void {
|
|
|
141
150
|
}
|
|
142
151
|
assert(count == MAX_TRANSFERS);
|
|
143
152
|
|
|
144
|
-
|
|
153
|
+
try stdout.print("starting benchmark...\n", .{});
|
|
145
154
|
try queue.execute();
|
|
146
155
|
assert(queue.end != null);
|
|
147
156
|
assert(queue.batches.empty());
|
|
148
157
|
|
|
149
158
|
var ms = queue.end.? - queue.start.?;
|
|
150
|
-
const transfer_type = if (IS_TWO_PHASE_COMMIT) "two-phase commit" else "";
|
|
159
|
+
const transfer_type = if (IS_TWO_PHASE_COMMIT) "two-phase commit " else "";
|
|
151
160
|
const result: i64 = @divFloor(@intCast(i64, transfers.len * 1000), ms);
|
|
152
|
-
|
|
153
|
-
|
|
161
|
+
try stdout.print("============================================\n", .{});
|
|
162
|
+
try stdout.print("{} {s}transfers per second\n\n", .{
|
|
154
163
|
result,
|
|
155
164
|
transfer_type,
|
|
156
165
|
});
|
|
157
|
-
|
|
166
|
+
try stdout.print("create_transfers max p100 latency per {} transfers = {}ms\n", .{
|
|
167
|
+
BATCH_SIZE,
|
|
158
168
|
queue.max_transfers_latency,
|
|
159
169
|
});
|
|
160
|
-
|
|
170
|
+
try stdout.print("commit_transfers max p100 latency per {} transfers = {}ms\n", .{
|
|
171
|
+
BATCH_SIZE,
|
|
161
172
|
queue.max_commits_latency,
|
|
162
173
|
});
|
|
163
|
-
|
|
164
|
-
if (result < @divFloor(@intCast(i64, BENCHMARK * (100 - RESULT_TOLERANCE)), 100)) {
|
|
165
|
-
log.warn("There has been a performance regression. previous benchmark={}\n", .{BENCHMARK});
|
|
166
|
-
}
|
|
167
174
|
}
|
|
168
175
|
|
|
169
176
|
const Batch = struct {
|
|
@@ -214,17 +221,27 @@ const TimedQueue = struct {
|
|
|
214
221
|
self.reset();
|
|
215
222
|
log.debug("executing batches...", .{});
|
|
216
223
|
|
|
217
|
-
var batch: ?Batch = self.batches.peek();
|
|
218
224
|
const now = std.time.milliTimestamp();
|
|
219
225
|
self.start = now;
|
|
220
|
-
if (
|
|
226
|
+
if (self.batches.head_ptr()) |starting_batch| {
|
|
221
227
|
log.debug("sending first batch...", .{});
|
|
222
228
|
self.batch_start = now;
|
|
229
|
+
var message = self.client.get_message() orelse {
|
|
230
|
+
@panic("Client message pool has been exhausted. Cannot execute batch.");
|
|
231
|
+
};
|
|
232
|
+
defer self.client.unref(message);
|
|
233
|
+
|
|
234
|
+
std.mem.copy(
|
|
235
|
+
u8,
|
|
236
|
+
message.buffer[@sizeOf(Header)..],
|
|
237
|
+
std.mem.sliceAsBytes(starting_batch.data),
|
|
238
|
+
);
|
|
223
239
|
self.client.request(
|
|
224
240
|
@intCast(u128, @ptrToInt(self)),
|
|
225
241
|
TimedQueue.lap,
|
|
226
242
|
starting_batch.operation,
|
|
227
|
-
|
|
243
|
+
message,
|
|
244
|
+
starting_batch.data.len,
|
|
228
245
|
);
|
|
229
246
|
}
|
|
230
247
|
|
|
@@ -234,20 +251,24 @@ const TimedQueue = struct {
|
|
|
234
251
|
}
|
|
235
252
|
}
|
|
236
253
|
|
|
237
|
-
pub fn lap(user_data: u128, operation: Operation, results: []const u8) void {
|
|
254
|
+
pub fn lap(user_data: u128, operation: Operation, results: Client.Error![]const u8) void {
|
|
238
255
|
const now = std.time.milliTimestamp();
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
256
|
+
const value = results catch |err| {
|
|
257
|
+
log.emerg("Client returned error={o}", .{@errorName(err)});
|
|
258
|
+
@panic("Client returned error during benchmarking.");
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
log.debug("response={s}", .{std.mem.bytesAsSlice(CreateAccountsResult, value)});
|
|
244
262
|
|
|
245
263
|
const self: *TimedQueue = @intToPtr(*TimedQueue, @intCast(usize, user_data));
|
|
246
264
|
const completed_batch: ?Batch = self.batches.pop();
|
|
247
265
|
assert(completed_batch != null);
|
|
248
266
|
assert(completed_batch.?.operation == operation);
|
|
249
267
|
|
|
250
|
-
log.debug("completed batch operation={} start={}", .{
|
|
268
|
+
log.debug("completed batch operation={} start={}", .{
|
|
269
|
+
completed_batch.?.operation,
|
|
270
|
+
self.batch_start,
|
|
271
|
+
});
|
|
251
272
|
const latency = now - self.batch_start.?;
|
|
252
273
|
switch (operation) {
|
|
253
274
|
.create_accounts => {},
|
|
@@ -264,14 +285,25 @@ const TimedQueue = struct {
|
|
|
264
285
|
else => unreachable,
|
|
265
286
|
}
|
|
266
287
|
|
|
267
|
-
|
|
268
|
-
|
|
288
|
+
if (self.batches.head_ptr()) |next_batch| {
|
|
289
|
+
var message = self.client.get_message() orelse {
|
|
290
|
+
@panic("Client message pool has been exhausted.");
|
|
291
|
+
};
|
|
292
|
+
defer self.client.unref(message);
|
|
293
|
+
|
|
294
|
+
std.mem.copy(
|
|
295
|
+
u8,
|
|
296
|
+
message.buffer[@sizeOf(Header)..],
|
|
297
|
+
std.mem.sliceAsBytes(next_batch.data),
|
|
298
|
+
);
|
|
299
|
+
|
|
269
300
|
self.batch_start = std.time.milliTimestamp();
|
|
270
301
|
self.client.request(
|
|
271
302
|
@intCast(u128, @ptrToInt(self)),
|
|
272
303
|
TimedQueue.lap,
|
|
273
304
|
next_batch.operation,
|
|
274
|
-
|
|
305
|
+
message,
|
|
306
|
+
next_batch.data.len,
|
|
275
307
|
);
|
|
276
308
|
} else {
|
|
277
309
|
log.debug("stopping timer...", .{});
|