Commit 50db84c
feat(cli): Add standalone --server and --client modes (#110)
* feat(cli): Add standalone --server and --client modes with full reporting
Add the ability to run the benchmark server and client as independent
processes, enabling cross-environment IPC testing (e.g., host and
container). Relates to #11.
Standalone mode features:
- --server flag starts a server that listens for client connections
- --client flag connects to a running server with retry logic
(100ms backoff, 30s timeout)
- Both async (Tokio) and blocking (std) execution modes supported
- Duration (-d) and message-count (-i) modes both supported
- Default transport endpoints work without extra flags
- Endpoint flags (--socket-path, --shared-memory-name,
--message-queue-name) promoted to user-facing
Reporting integration:
- Full ResultsManager/MetricsCollector integration for structured
output (JSON, streaming CSV, console summary with HDR percentiles)
- Server-side one-way latency measurement using monotonic clock
(accurate for same-host and container scenarios)
- Round-trip latency with per-message streaming support
Code quality:
- Shared helpers: dispatch_server_message(), retry constants
- 25 tests covering CLI parsing, transport config, server dispatch,
connection retry, shutdown, duration mode, one-way, round-trip
- Explicit MessageType::Shutdown on client disconnect
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: Support send_delay and include_first_message in standalone client
- Add --send-delay support: inserts a configurable pause after each
message send (blocking uses thread::sleep, async uses tokio::sleep)
- Add --include-first-message support: when false (default), sends a
canary message before measurement to warm up the connection, matching
the existing BenchmarkRunner behavior
- Applied to both one-way and round-trip tests in both blocking and
async client paths
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* perf: Eliminate per-message heap allocation in standalone client
Reuse a single Message struct across loop iterations instead of
calling Message::new() with payload.clone() on every send. The
message id and timestamp are updated in-place before each send.
This removes one Vec<u8> heap allocation per message in the
measurement loop, reducing allocation overhead that can skew
latency results, especially for small messages.
Applied to both one-way and round-trip tests in both blocking
and async client paths.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: Add concurrency support for standalone client/server
Server-side multi-accept:
- TCP and UDS servers now accept multiple concurrent connections,
spawning a handler thread per client with its own MetricsCollector
- Grace period after first client prevents premature server exit
- SHM and PMQ fall back to single-client mode with a warning
- Server aggregates one-way latency metrics across all handlers
Client-side multi-threaded execution:
- Blocking client spawns N worker threads, each with its own transport
connection, MetricsCollector, and message loop
- Async client uses tokio::task::JoinSet for concurrent workers
- Results aggregated via MetricsCollector::aggregate_worker_metrics()
- Per-message streaming disabled for concurrent mode (aggregated only)
Transport additions:
- BlockingTcpSocket::from_stream() wraps pre-accepted TcpStream
- BlockingUnixDomainSocket::from_stream() wraps pre-accepted UnixStream
Shared helpers:
- handle_client_connection() -- per-client message dispatch and metrics
- aggregate_and_print_server_metrics() -- shared aggregation logic
Tests:
- test_standalone_concurrent_tcp_round_trip (3 concurrent clients)
- test_handle_client_connection_round_trip (dispatch correctness)
- test_handle_client_connection_one_way_metrics (metrics recording)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test: Add coverage for concurrency, from_stream, and aggregation
- test_standalone_concurrent_tcp_one_way: multi-accept server with 2
concurrent one-way clients, verifying server-side metrics recording
- test_tcp_from_stream_send_receive: BlockingTcpSocket::from_stream()
full send/receive round-trip
- test_uds_from_stream_send_receive: BlockingUnixDomainSocket::from_stream()
full send/receive round-trip (unix-only)
- test_concurrency_forced_to_one_for_shm: CLI parsing for SHM with
concurrency > 1
- test_aggregate_and_print_empty_collectors: empty input edge case
- test_aggregate_and_print_single_collector: single collector with data
Total binary tests: 34.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: Add async multi-accept server and remove unused parameter
- Add multi-accept support for async TCP and UDS servers, matching
the blocking server's concurrency support. Uses tokio::net listeners
with spawn_blocking for per-client handler threads.
- Remove unused _args parameter from run_standalone_server_async
- Replace inline latency printing in async server with shared
print_server_one_way_latency helper
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: Use OS-assigned ports in tests and document grace period
- Replace all 12 hardcoded test ports (18301-18314) with OS-assigned
ports via get_free_port() helper (binds to port 0, extracts assigned
port). Prevents port conflicts in parallel test runs and with other
processes.
- Extract 2-second multi-accept grace period into
SERVER_ACCEPT_GRACE_PERIOD constant with documentation explaining
the behavior and limitation.
- Document the grace period in --server CLI help text so users know
concurrent clients should connect within 2 seconds of each other.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: Set streams to blocking mode after tokio into_std conversion
tokio::net::TcpStream::into_std() leaves the stream in non-blocking
mode (set by tokio for epoll/kqueue). The blocking transport's
read_exact/write_all calls then fail with WouldBlock errors,
causing immediate disconnection.
Fix: call set_nonblocking(false) on streams after into_std() in
both TCP and UDS async multi-accept servers.
Add test_standalone_async_concurrent_tcp_round_trip to exercise
the async multi-accept path (tokio accept + spawn_blocking +
from_stream + handle_client_connection).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test: Strengthen test assertions for real-world correctness
- test_standalone_blocking_tcp_one_way: verify server received exact
message count with correct sequential IDs, add shutdown message
- test_standalone_blocking_tcp_duration_round_trip: verify response
IDs match requests, assert count > 10 for 200ms test, add shutdown
- test_standalone_blocking_tcp_duration_one_way: verify server received
exact count with sequential IDs, assert count > 10 for 200ms test
- test_concurrency_forced_to_one_for_shm: test actual concurrency
forcing logic instead of just CLI parsing
- test_standalone_concurrent_tcp_one_way: assert exact message count
per handler instead of just "greater than zero"
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: Address round 2 review feedback
- Clean up garbled doc comment on async concurrent test (editing
artifacts from multiple rewrites)
- Replace silent panic swallowing in async multi-accept servers:
try_join_next().transpose() silently dropped JoinErrors from
panicked handler tasks. Now logs warnings via warn!().
- Extract effective_concurrency() helper to deduplicate the
concurrency-forcing logic (was copied in blocking client, async
client, and test). Test now calls the actual helper instead of
reimplementing the logic inline.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test: Add real-world scenario tests for coverage and correctness
- test_standalone_large_payload_integrity: 4KB payloads with
recognizable byte pattern, server echoes back, client verifies
content byte-for-byte to catch corruption
- test_handle_client_connection_filters_canary: verifies warmup
canary messages (id=u64::MAX) are excluded from one-way metrics
- test_handle_client_connection_mixed_message_types: interleaved
OneWay and Request messages on a single connection, verifies
correct metrics recording and response dispatch
- test_aggregate_and_print_multiple_collectors: aggregation across
2 collectors with different latency distributions
- test_effective_concurrency_all_mechanisms: covers UDS, PMQ, SHM,
TCP, and concurrency=1 edge case
Total binary tests: 40.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: Set accepted streams to blocking mode in multi-accept servers
Accepted TCP/UDS streams inherit non-blocking mode from the
listener (set for the accept poll loop). The handler threads need
blocking mode for the transport's read_exact/write_all operations.
This is the blocking-server equivalent of the async into_std fix
in commit 8723429. Without this fix, standalone server handlers
immediately disconnect from clients.
Applies to both run_standalone_server_blocking_multi_accept_tcp
and _uds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: Address review feedback - grace period, quiet flag, mutex safety
- Fix grace period bug: reset timer on every new connection, not just
the first. Prevents premature server exit between one-way and
round-trip test phases when using concurrency > 1. Applied to all
four multi-accept servers (blocking TCP/UDS, async TCP/UDS).
- Honor --quiet flag in standalone server and client. When set,
suppress all tracing output to stderr.
- Handle poisoned mutex gracefully: use unwrap_or_else(|e| e.into_inner())
instead of unwrap() on mutex locks. If a handler thread panics while
holding the lock, other threads can still push their metrics instead
of cascade-panicking.
- Add defensive --shm-direct guard in standalone server and client:
returns error if --shm-direct is used without --blocking. This is
normally enforced by main() but the guard protects against future
refactoring that might change the dispatch order.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: Address review feedback - multiple correctness and quality fixes
- Fix grace period bug: reset timer on every new connection, not just
the first. Prevents premature server exit between one-way and
round-trip test phases when using concurrency > 1. Applied to all
four multi-accept servers (blocking TCP/UDS, async TCP/UDS).
- Honor --quiet flag in standalone server and client. When set,
suppress all tracing output to stderr.
- Handle poisoned mutex gracefully: use unwrap_or_else(|e| e.into_inner())
instead of unwrap() on mutex locks in handler threads.
- Add defensive --shm-direct guard in standalone server and client.
- Add socket buffer tuning (recv/send buffer sizes) to multi-accept
TCP servers to match normal transport behavior.
- Fix integer division remainder: last worker now receives any extra
messages when msg_count is not evenly divisible by concurrency.
- Document empty response payloads as intentional design matching
existing benchmark runner behavior.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: Add receive_blocking_timed for accurate one-way latency
Add receive_blocking_timed() to the BlockingTransport trait that
captures a monotonic timestamp after raw bytes are read but before
bincode deserialization. This excludes deserialization overhead from
one-way latency measurements.
- Add default implementation on BlockingTransport trait (backward
compatible -- captures timestamp after full receive)
- Override in TCP, UDS, and SHM blocking transports to place
timestamp between raw I/O read and deserialization
- SHM-direct uses default (no bincode deserialization to exclude)
- Update handle_client_connection and standalone single-client
server to use receive_blocking_timed
Impact is most visible with large payloads where deserialization
is non-trivial. 64KB one-way TCP test shows min latency dropped
from 41us (post-deserialize) to 14us (pre-deserialize), a ~27us
improvement representing the bincode deserialization time excluded
from measurement. Mean dropped 28% (73us to 52us) and P99 dropped
14% (132us to 113us).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: Update MessageLatencyRecord calls for PR #105 compatibility
PR #105 (Fix/streaming timestamps) added send_timestamp_ns parameter
to MessageLatencyRecord::new(). Update all 4 call sites in standalone
client to capture wall-clock timestamp at send time and pass it as
the 6th argument.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: Move standalone logic from main.rs to library crate
Move ~3100 lines of standalone client/server code from the binary
crate (main.rs) into two new library modules, following the existing
flat-file convention (benchmark.rs/benchmark_blocking.rs pattern).
Structure:
- standalone_server.rs (1982 lines): constants, shared helpers,
server dispatch, multi-accept TCP/UDS, async server paths
- standalone_client.rs (1146 lines): retry helpers, client dispatch,
single/concurrent blocking and async paths
- main.rs reduced from ~4200 to ~1120 lines (thin dispatch layer)
Additional changes:
- Promote logging.rs from binary-private to library-public module
- Move set_affinity() to utils.rs as pub function
- All standalone functions now pub for tarpaulin coverage measurement
and integration test access
No behavioral changes. All 374 tests pass. Benchmark comparison
across 3 runs confirms no performance regression (mean latencies
within 2-5% run-to-run variance).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: Improve server resilience and error visibility
- Socket configuration failures (set_nonblocking, set_nodelay) in
multi-accept servers now log a warning and skip the bad connection
instead of crashing the entire server with ?
- Thread join panics in blocking multi-accept servers now logged
with warn! instead of silently dropped with let _ =
- Streaming latency record failures in client now logged with
debug! instead of silently swallowed
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test: Comprehensive coverage improvements for standalone modules
Server tests (standalone_server.rs, 82.7% coverage):
- test_multi_accept_tcp_server_direct: exercises multi-accept TCP directly
- test_single_server_direct: exercises blocking single-client directly
- test_server_blocking_dispatch: exercises dispatch logic
- test_server_blocking_dispatch_uds: exercises UDS dispatch branch
- test_async_multi_accept_tcp_full: exercises async multi-accept TCP
- test_async_single_server_path: exercises async single-client
- test_async_single_server_one_way_metrics: async one-way metrics
- test_async_multi_accept_uds_full: exercises async UDS multi-accept
- test_multi_accept_server_with_delayed_client: slow sender resilience
- test_multi_accept_server_duration_one_way: duration mode with multi-accept
- test_async_multi_accept_server_duration_one_way: async duration mode
- test_handle_client_connection_send_failure: client disconnect error path
- test_single_server_client_disconnect: single server send error path
- test_multi_accept_server_survives_bad_client: garbage input resilience
- test_handle_client_connection_garbage_input: deserialization error path
- test_run_standalone_server_full_dispatch: full entry point dispatch
- test_run_standalone_server_rejects_all_via_dispatch: 'all' validation
- test_run_standalone_server_rejects_shm_direct: shm-direct guard
- test_run_standalone_server_verbose: -vv logging level branches
- test_aggregate_server_metrics_from_handlers: real handler data
- test_print_server_one_way_latency_with_data/zero: print paths
Client tests (standalone_client.rs, 86.3% coverage):
- test_client_blocking_tcp_round_trip/one_way: single client paths
- test_client_blocking_tcp_duration_round_trip/one_way: duration mode
- test_client_blocking_tcp_concurrent_round_trip/one_way: concurrent
- test_client_async_single_round_trip/one_way: async single
- test_client_async_duration_round_trip/one_way: async duration
- test_client_async_concurrent_round_trip/one_way: async concurrent
- test_client_blocking_with_send_delay: send_delay round-trip branch
- test_client_blocking_one_way_with_send_delay: send_delay one-way branch
- test_client_blocking_with_streaming_output: JSON streaming
- test_client_blocking_combined_streaming: combined mode streaming
- test_client_blocking_csv_streaming: CSV streaming
- test_client_blocking_concurrent_duration_one_way: concurrent duration
- test_client_async_concurrent_duration_one_way: async concurrent duration
- test_run_standalone_client_full_dispatch: full entry point dispatch
- test_run_standalone_client_rejects_all_via_dispatch: 'all' validation
- test_run_standalone_client_rejects_shm_direct: shm-direct guard
- test_connect_async_with_retry_succeeds: async retry path
Also: changed tracing .init() to .try_init() with eprintln fallback
in both server and client for test compatibility.
Coverage: standalone_server 82.7%, standalone_client 86.3%, combined 84.8%
Total lib tests: 355.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* perf: Reduce multi-accept server polling interval from 50ms to 5ms
Reduce the non-blocking accept loop sleep from 50ms to 5ms in both
TCP and UDS multi-accept servers. This cuts connection acceptance
latency by 10x with no portability concerns.
Discovered during hands-on validation testing of standalone concurrent
mode, where the 50ms polling interval was the primary contributor to
elevated tail latency under multi-client workloads.
Improvement with -c 4 concurrent clients:
- RT P95: -46% (65.9us -> 35.5us)
- RT P99: -49% (91.4us -> 46.9us)
- Throughput: +66% (94.9 -> 157.1 MB/s)
Single-client workloads also benefit from faster initial connection
acceptance (P99 improved 4-7% across all test modes).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: Address PR #110 review feedback (issues 1-11)
- Add 60s idle timeout to prevent server hang when no client connects
- Log canary/shutdown send errors (warn for canary, debug for shutdown)
- Wire concurrent streaming: workers collect MessageLatencyRecord and
stream through ResultsManager after completion
- Reject multiple mechanisms in standalone mode with clear error
- Add debug logging on server receive errors for diagnostics
- Add per-worker warmup in concurrent mode (fixes metadata mismatch)
- Document two-phase reconnection behavior in concurrent mode
- Add SIGINT/SIGTERM signal handler via ctrlc crate for graceful
server shutdown and resource cleanup
- Add receive_blocking_timed override for PMQ transport to exclude
deserialization from one-way latency measurement
- Add 11 integration tests spawning separate server/client processes
- Fix misleading test comment on garbage input handler
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: CI compatibility for MSRV and lint checks
- Drop ctrlc "termination" feature (requires Rust 1.75+ due to nix
static zeroed); SIGINT still handled, SIGTERM uses default OS behavior
- Remove unused BlockingTcpSocket import in canary failure test
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: Pin ctrlc to 3.4.5 for MSRV 1.70 compatibility
ctrlc 3.5+ uses std::mem::zeroed() in statics which requires Rust 1.75+.
Version 3.4.5 does not have this issue and supports Rust 1.69+.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: Use cross-platform mechanisms in multiple-mechanism rejection tests
Tests used "tcp uds" but UDS is not a valid mechanism on Windows,
causing clap to reject the args before reaching our validation code.
Changed to "tcp shm" which exists on all platforms.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: Use platform-independent temp dir in output file integration test
The test hardcoded /tmp/ which doesn't exist on Windows. Use
std::env::temp_dir() for cross-platform compatibility.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: Address PR #110 follow-up review (4 additional findings)
- Add sentinel connection in concurrent client to prevent server from
exiting between one-way and round-trip phases (keeps a connection
open across both phases so the server's grace period check never
triggers prematurely)
- Surface accept-loop errors: upgrade from debug to warn logging and
return Err when accept fails before any client connects
- Fix duration precision loss: use as_secs_f64() instead of as_secs()
when passing duration to spawned server process
- Propagate latency file write errors instead of silently discarding
- Add integration tests for concurrent both-tests scenario
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* style: Fix formatting issues caught by CI
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>1 parent 1435ca2 commit 50db84c
18 files changed
Lines changed: 6881 additions & 63 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
53 | 53 | | |
54 | 54 | | |
55 | 55 | | |
| 56 | + | |
| 57 | + | |
56 | 58 | | |
57 | 59 | | |
58 | 60 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
102 | 102 | | |
103 | 103 | | |
104 | 104 | | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
105 | 109 | | |
106 | 110 | | |
107 | 111 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
287 | 287 | | |
288 | 288 | | |
289 | 289 | | |
| 290 | + | |
| 291 | + | |
290 | 292 | | |
291 | 293 | | |
292 | 294 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
377 | 377 | | |
378 | 378 | | |
379 | 379 | | |
| 380 | + | |
| 381 | + | |
380 | 382 | | |
381 | 383 | | |
382 | 384 | | |
| |||
766 | 768 | | |
767 | 769 | | |
768 | 770 | | |
769 | | - | |
| 771 | + | |
770 | 772 | | |
771 | 773 | | |
772 | 774 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
82 | 82 | | |
83 | 83 | | |
84 | 84 | | |
| 85 | + | |
85 | 86 | | |
86 | 87 | | |
87 | 88 | | |
| |||
366 | 367 | | |
367 | 368 | | |
368 | 369 | | |
369 | | - | |
| 370 | + | |
370 | 371 | | |
371 | | - | |
372 | | - | |
373 | | - | |
374 | | - | |
375 | | - | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
376 | 398 | | |
377 | | - | |
378 | | - | |
379 | | - | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
380 | 425 | | |
381 | 426 | | |
382 | | - | |
383 | | - | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
384 | 433 | | |
385 | 434 | | |
386 | | - | |
387 | | - | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
388 | 441 | | |
389 | 442 | | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
390 | 451 | | |
391 | 452 | | |
392 | 453 | | |
| |||
993 | 1054 | | |
994 | 1055 | | |
995 | 1056 | | |
| 1057 | + | |
| 1058 | + | |
| 1059 | + | |
| 1060 | + | |
| 1061 | + | |
| 1062 | + | |
| 1063 | + | |
| 1064 | + | |
| 1065 | + | |
| 1066 | + | |
| 1067 | + | |
| 1068 | + | |
| 1069 | + | |
| 1070 | + | |
| 1071 | + | |
| 1072 | + | |
| 1073 | + | |
| 1074 | + | |
| 1075 | + | |
| 1076 | + | |
| 1077 | + | |
| 1078 | + | |
| 1079 | + | |
| 1080 | + | |
| 1081 | + | |
| 1082 | + | |
| 1083 | + | |
| 1084 | + | |
| 1085 | + | |
| 1086 | + | |
| 1087 | + | |
| 1088 | + | |
| 1089 | + | |
| 1090 | + | |
| 1091 | + | |
| 1092 | + | |
| 1093 | + | |
| 1094 | + | |
| 1095 | + | |
| 1096 | + | |
| 1097 | + | |
| 1098 | + | |
| 1099 | + | |
| 1100 | + | |
| 1101 | + | |
| 1102 | + | |
| 1103 | + | |
| 1104 | + | |
| 1105 | + | |
| 1106 | + | |
| 1107 | + | |
| 1108 | + | |
| 1109 | + | |
| 1110 | + | |
996 | 1111 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1185 | 1185 | | |
1186 | 1186 | | |
1187 | 1187 | | |
| 1188 | + | |
| 1189 | + | |
| 1190 | + | |
| 1191 | + | |
| 1192 | + | |
| 1193 | + | |
| 1194 | + | |
| 1195 | + | |
| 1196 | + | |
| 1197 | + | |
| 1198 | + | |
| 1199 | + | |
| 1200 | + | |
| 1201 | + | |
| 1202 | + | |
1188 | 1203 | | |
1189 | 1204 | | |
1190 | 1205 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
471 | 471 | | |
472 | 472 | | |
473 | 473 | | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
474 | 512 | | |
475 | 513 | | |
476 | 514 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
756 | 756 | | |
757 | 757 | | |
758 | 758 | | |
| 759 | + | |
| 760 | + | |
| 761 | + | |
| 762 | + | |
| 763 | + | |
| 764 | + | |
| 765 | + | |
| 766 | + | |
| 767 | + | |
| 768 | + | |
| 769 | + | |
| 770 | + | |
| 771 | + | |
| 772 | + | |
| 773 | + | |
| 774 | + | |
| 775 | + | |
| 776 | + | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
| 791 | + | |
| 792 | + | |
| 793 | + | |
| 794 | + | |
759 | 795 | | |
760 | 796 | | |
761 | 797 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
649 | 649 | | |
650 | 650 | | |
651 | 651 | | |
| 652 | + | |
| 653 | + | |
| 654 | + | |
| 655 | + | |
| 656 | + | |
| 657 | + | |
| 658 | + | |
| 659 | + | |
| 660 | + | |
652 | 661 | | |
653 | 662 | | |
654 | 663 | | |
| |||
0 commit comments