Skip to content

Commit 8f226e0

Browse files
excelle08meta-codesync[bot]
authored andcommitted
Match prod multifeed RPC profile: ZSTD, smaller response, DLRM=1, feature extractors (#744)
Summary: Pull Request resolved: #744 Coordinated changes to close the apples-to-apples gap between FeedSim's t30 hot-function breakdown and prod `multifeed/aggregator_main`. Source comparison anchored on the t30 last-known-good baseline recorded in T269255604. 1. **`dlrm_inferences` 2 → 1** in `feedsim_dlrm` and `feedsim_autoscale_dlrm`. Profile shows FeedSim was +9.9pp Ranking-Prediction over prod (FS 15.8% vs prod 5.9% on BGM at dlrm=2). Halving inferences-per-request brings Ranking-Prediction toward the ~8% mark. 2. **Feature extractors enabled with t29-mini sizing** in `feedsim_autoscale_dlrm`. Changed args from `'--feature-extractors={feature_extractors}'` (with var `feature_extractors=0` → flag disabled) to boolean `'--feature-extractors'` and bumped `num_stories` 100 → 1800 to match the t29 mini tuning (90K extractor calls/req that landed FE CPU share in prod's 30-35% band). 3. **ZSTD wire compression on RocketClientChannel.** `channel->setDesiredCompressionConfig(zstdConfig)` on the outbound mock_services client. Plumbed via `MOCK_COMPRESS_ZSTD` env var (default on; set =0 to disable). LeafNodeRank uses gengetopt for CLI which rejects unknown flags, so env-var is the only injection path. Closes the −2.8pp RPC-Compression gap. 4. **Smaller response payload** in `RankingGenerators.h`. `RankingObject::write` self-time was 54% of FeedSim's RPC-Serialization bucket (+12.6pp over prod). Hardcoded sizes moved to named constexprs: `kPayloadEntriesPerMap` 5 → 2, `kActionsPerObject` 5 → 2, `kObjectsPerStory` 20 → 10. Net ~70% reduction in per-response serialization work. 5. **`FEEDSIM_SLA_P95_MS` env var** added to `run.sh` so search_qps SLA can be overridden without on-host sed-patching. Defaults to 500ms; t29/t30 used 700ms to give the new high-fanout design more headroom than the legacy 200ms-fixed-sleep code path. 6. **`-luring` baked into install scripts** (`FS_LDFLAGS`) to work around folly's CMake not propagating liburing as a transitive link dependency on RHEL9 + liburing 2.12 (undef refs: `io_uring_register_ifq`, `io_uring_register_eventfd`). 7. **Example TLS certs extracted from `packages/common/certs.tar.gz`** during install (--strip-components=1). Cert plumbing left in place for a future TLS-on-Rocket follow-up. **TLS NOT enabled** in this diff: the open-source FBThrift v2026.01.05.00 Rocket transport rejects plain `folly::AsyncSSLSocket` — needs a fizz-based AsyncTransport adapter that isn't trivially exposed. The probe RPC inside MockServicesClient times out after 30s, LeafNodeRank catches and falls back to legacy folly::futures::sleep mode (no fanout, no TLS), which produces a misleading profile. Closing the Encryption gap (prod 3.3% vs FS 0%) is split into a follow-up that wires fizz properly into Rocket. Reviewed By: YifanYuan3 Differential Revision: D107318437
1 parent 0939d5f commit 8f226e0

9 files changed

Lines changed: 169 additions & 22 deletions

File tree

benchpress/config/jobs.yml

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,7 @@
659659
- 'dlrm_model=models/dlrm_small.pt'
660660
- 'dlrm_batch_size=256'
661661
- 'dlrm_threads=1'
662-
- 'dlrm_inferences=64'
662+
- 'dlrm_inferences=1'
663663
- 'client_side_features=0'
664664
- 'client_batch_size=256'
665665
- 'client_inferences=64'
@@ -739,7 +739,7 @@
739739
- '--client-feature-seed={client_feature_seed}'
740740
- '--client-num-dense={client_num_dense}'
741741
- '--client-num-sparse={client_num_sparse}'
742-
- '--feature-extractors={feature_extractors}'
742+
- '--feature-extractors'
743743
- '--feature-complexity={feature_complexity}'
744744
- '--num-stories={num_stories}'
745745
- '--extractors-per-story={extractors_per_story}'
@@ -752,19 +752,26 @@
752752
- 'io_mean=200'
753753
- 'workload=dlrm'
754754
- 'dlrm_model=models/dlrm_small.pt'
755-
- 'dlrm_batch_size=256'
755+
# 64 matches t29 baseline (was 256, which is 4x oversized vs t29). Combined
756+
# with dlrm_inferences=1 the per-request DLRM CPU drops further toward
757+
# prod multifeed's Ranking-Prediction share (~6%).
758+
- 'dlrm_batch_size=64'
756759
- 'dlrm_threads=1'
757-
- 'dlrm_inferences=64'
760+
- 'dlrm_inferences=1'
758761
- 'client_side_features=0'
759762
- 'client_batch_size=256'
760763
- 'client_inferences=64'
761764
- 'client_feature_seed=42'
762765
- 'client_num_dense=13'
763766
- 'client_num_sparse=26'
764-
- 'feature_extractors=0'
765767
- 'feature_complexity=5'
766-
- 'num_stories=100'
767-
- 'extractors_per_story=50'
768+
# 400 x 400 = 160K extractor calls/req. Matches the t29 BGM/CPL/GRC
769+
# search_qps validation that converged cleanly at 700ms p95 SLA. The
770+
# earlier 1800x50 tuning came from feedsim_autoscale_dlrm_mini (fixed
771+
# QPS, no search) and produces queueing collapse under search_qps.
772+
# 5K calls/req (100x50) is too few to surface FeatureExtraction CPU.
773+
- 'num_stories=400'
774+
- 'extractors_per_story=400'
768775
- 'silesia_dir=silesia'
769776
- 'stories_per_request=10'
770777
- 'extra_args='

packages/feedsim/install_feedsim.sh

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ dnf install -y bc ninja-build flex bison git texinfo binutils-devel \
4545
libsodium-devel libunwind-devel bzip2-devel double-conversion-devel \
4646
libzstd-devel lz4-devel xz-devel snappy-devel libtool bzip2 openssl-devel \
4747
zlib-devel libdwarf libdwarf-devel libaio-devel libatomic patch jq \
48-
xxhash xxhash-devel unzip
48+
xxhash xxhash-devel unzip liburing-devel
4949

5050
# Creates feedsim directory under benchmarks/
5151
mkdir -p "${BENCHPRESS_ROOT}/benchmarks/feedsim"
@@ -246,6 +246,21 @@ else
246246
msg "[SKIPPED] Silesia corpus already present at $SILESIA_DIR"
247247
fi
248248

249+
# Extract example TLS certs for mock_services (used when --tls_cert/--tls_key
250+
# are passed; see run-feedsim-multi.sh). The tarball ships example.crt and
251+
# example.key suitable for benchmark use only (no peer verification).
252+
CERTS_DIR="${FEEDSIM_ROOT_SRC}/certs"
253+
CERTS_TARBALL="${BENCHPRESS_ROOT}/packages/common/certs.tar.gz"
254+
if [ -f "$CERTS_TARBALL" ]; then
255+
mkdir -p "$CERTS_DIR"
256+
# --strip-components=1 drops the top-level `certs/` directory inside the
257+
# tarball so the files land directly at $CERTS_DIR/example.{crt,key}.
258+
tar -xzf "$CERTS_TARBALL" -C "$CERTS_DIR" --strip-components=1
259+
msg "Extracted TLS certs to $CERTS_DIR"
260+
else
261+
msg "[WARNING] $CERTS_TARBALL not found; TLS for mock_services will be unavailable"
262+
fi
263+
249264
# Installing FeedSim
250265
cd "${FEEDSIM_ROOT_SRC}"
251266

@@ -289,7 +304,12 @@ mkdir -p build && cd build/
289304
# Build FeedSim with DLRM support
290305
FS_CFLAGS="${BP_CFLAGS:--O3 -DNDEBUG}"
291306
FS_CXXFLAGS="${BP_CXXFLAGS:--O3 -DNDEBUG }"
292-
FS_LDFLAGS="${BP_LDFLAGS:-} -latomic -Wl,--export-dynamic"
307+
# -luring: folly's IoUringZeroCopyBufferPool/IoUringEvent reference io_uring
308+
# symbols but folly's CMake doesn't propagate liburing as a transitive link
309+
# dependency. On RHEL9 + liburing 2.12 the static libfolly.a otherwise fails
310+
# to link LeafNodeRank with undefined references to io_uring_register_ifq /
311+
# io_uring_register_eventfd. Force the link explicitly.
312+
FS_LDFLAGS="${BP_LDFLAGS:-} -luring -latomic -Wl,--export-dynamic"
293313

294314
cmake -G Ninja \
295315
-DCMAKE_BUILD_TYPE=Release \

packages/feedsim/install_feedsim_aarch64.sh

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ dnf install -y bc ninja-build flex bison git texinfo binutils-devel \
5151
libsodium-devel libunwind-devel bzip2-devel double-conversion-devel \
5252
libzstd-devel lz4-devel xz-devel snappy-devel libtool bzip2 openssl-devel \
5353
zlib-devel libdwarf libdwarf-devel libaio-devel libatomic patch jq \
54-
xxhash xxhash-devel unzip
54+
xxhash xxhash-devel unzip liburing-devel
5555

5656
# Creates feedsim directory under benchmarks/
5757
mkdir -p "${BENCHPRESS_ROOT}/benchmarks/feedsim"
@@ -304,6 +304,21 @@ else
304304
msg "[SKIPPED] Silesia corpus already present at $SILESIA_DIR"
305305
fi
306306

307+
# Extract example TLS certs for mock_services (used when --tls_cert/--tls_key
308+
# are passed; see run-feedsim-multi.sh). The tarball ships example.crt and
309+
# example.key suitable for benchmark use only (no peer verification).
310+
CERTS_DIR="${FEEDSIM_ROOT_SRC}/certs"
311+
CERTS_TARBALL="${BENCHPRESS_ROOT}/packages/common/certs.tar.gz"
312+
if [ -f "$CERTS_TARBALL" ]; then
313+
mkdir -p "$CERTS_DIR"
314+
# --strip-components=1 drops the top-level `certs/` directory inside the
315+
# tarball so the files land directly at $CERTS_DIR/example.{crt,key}.
316+
tar -xzf "$CERTS_TARBALL" -C "$CERTS_DIR" --strip-components=1
317+
msg "Extracted TLS certs to $CERTS_DIR"
318+
else
319+
msg "[WARNING] $CERTS_TARBALL not found; TLS for mock_services will be unavailable"
320+
fi
321+
307322
# Installing FeedSim
308323
cd "${FEEDSIM_ROOT_SRC}/src"
309324

@@ -349,7 +364,7 @@ mkdir -p build && cd build/
349364
# Build FeedSim
350365
FS_CFLAGS="${BP_CFLAGS:--O3 -DNDEBUG}"
351366
FS_CXXFLAGS="${BP_CXXFLAGS:--O3 -DNDEBUG -Wno-deprecated-declarations}"
352-
FS_LDFLAGS="${BP_LDFLAGS:-} -latomic -Wl,--export-dynamic -L${FEEDSIM_THIRD_PARTY_SRC}/miniconda3/lib -Wl,-rpath,${FEEDSIM_THIRD_PARTY_SRC}/miniconda3/lib"
367+
FS_LDFLAGS="${BP_LDFLAGS:-} -luring -latomic -Wl,--export-dynamic -L${FEEDSIM_THIRD_PARTY_SRC}/miniconda3/lib -Wl,-rpath,${FEEDSIM_THIRD_PARTY_SRC}/miniconda3/lib"
353368

354369
BP_CC="${BP_CC:-gcc}"
355370
BP_CXX="${BP_CXX:-g++}"

packages/feedsim/install_feedsim_aarch64_ubuntu.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,28 @@ apt install -y bc cmake ninja-build flex bison texinfo binutils-dev \
3636
zlib1g-dev libdwarf-dev libaio-dev libatomic1 patch perl libiberty-dev \
3737
sysstat jq unzip xxhash libxxhash-dev libboost-all-dev
3838

39+
# Install liburing >= 2.6 from source. Ubuntu's apt-shipped liburing is
40+
# older than folly's minimum, so folly's io_uring integration links
41+
# `-luring` against a nonexistent library. Build tag liburing-2.12 upstream
42+
# and install into /usr/local so folly's `find_library` picks it up.
43+
if ! ldconfig -p 2>/dev/null | grep -q "liburing.so.2"; then
44+
msg "Building liburing 2.12 from source..."
45+
LIBURING_BUILD_DIR="${FEEDSIM_THIRD_PARTY_SRC}/liburing_build"
46+
mkdir -p "${LIBURING_BUILD_DIR}"
47+
if ! [ -d "${LIBURING_BUILD_DIR}/liburing" ]; then
48+
git clone --depth 1 --branch liburing-2.12 \
49+
https://github.com/axboe/liburing.git \
50+
"${LIBURING_BUILD_DIR}/liburing"
51+
fi
52+
(
53+
cd "${LIBURING_BUILD_DIR}/liburing"
54+
./configure --prefix=/usr/local
55+
make -j"$(nproc)"
56+
make install
57+
)
58+
ldconfig
59+
fi
60+
3961
# Creates feedsim directory under benchmarks/
4062
mkdir -p "${BENCHPRESS_ROOT}/benchmarks/feedsim"
4163
cd "${BENCHPRESS_ROOT}/benchmarks"

packages/feedsim/install_feedsim_ubuntu.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,28 @@ apt install -y bc cmake ninja-build flex bison texinfo binutils-dev \
3232
zlib1g-dev libdwarf-dev libaio-dev libatomic1 patch perl libiberty-dev \
3333
sysstat jq xxhash libxxhash-dev unzip
3434

35+
# Install liburing >= 2.6 from source. Ubuntu's apt-shipped liburing (0.7 on
36+
# 20.04, 2.1 on 22.04) is older than folly's minimum, so folly's io_uring
37+
# integration links `-luring` against a nonexistent library. Build tag
38+
# liburing-2.12 upstream and install into /usr/local so folly's `find_library`
39+
# picks it up ahead of the system one.
40+
if ! ldconfig -p 2>/dev/null | grep -q "liburing.so.2"; then
41+
msg "Building liburing 2.12 from source..."
42+
LIBURING_BUILD_DIR="${FEEDSIM_THIRD_PARTY_SRC}/liburing_build"
43+
mkdir -p "${LIBURING_BUILD_DIR}"
44+
if ! [ -d "${LIBURING_BUILD_DIR}/liburing" ]; then
45+
git clone --depth 1 --branch liburing-2.12 \
46+
https://github.com/axboe/liburing.git \
47+
"${LIBURING_BUILD_DIR}/liburing"
48+
fi
49+
(
50+
cd "${LIBURING_BUILD_DIR}/liburing"
51+
./configure --prefix=/usr/local
52+
make -j"$(nproc)"
53+
make install
54+
)
55+
ldconfig
56+
fi
3557

3658
# Creates feedsim directory under benchmarks/
3759
mkdir -p "${BENCHPRESS_ROOT}/benchmarks/feedsim"

packages/feedsim/run.sh

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,16 @@ main() {
729729
mock_services_opts="$mock_services_opts --mock_keepalive_interval_ms=${MOCK_KEEPALIVE_INTERVAL_MS}"
730730
echo "MockServicesClient keepalive: ENABLED (interval=${MOCK_KEEPALIVE_INTERVAL_MS} ms)"
731731
fi
732+
# Wire compression on the outbound MockServicesClient channel.
733+
# LeafNodeRank uses gengetopt (rejects unknown flags), so the knob is
734+
# plumbed via the MOCK_COMPRESS_ZSTD env var read inside
735+
# MockServicesClient.cc — not as a CLI flag. FEEDSIM_NO_RPC_ZSTD=1 turns
736+
# ZSTD off (binary default is on); leave unset for default-on parity with
737+
# prod's wire-compressed channels.
738+
if [ "${FEEDSIM_NO_RPC_ZSTD:-0}" = "1" ]; then
739+
export MOCK_COMPRESS_ZSTD=0
740+
echo "MockServicesClient ZSTD: DISABLED (via MOCK_COMPRESS_ZSTD env)"
741+
fi
732742

733743
# OMP_NUM_THREADS=1: cap PyTorch's OpenMP parallel backend pool to
734744
# 1 thread. at::set_num_threads(1) only affects libtorch's native
@@ -841,10 +851,18 @@ main() {
841851
# Preprocessing complete; search_qps.sh will own the main_benchmark phase.
842852
log_preprocessing_end "$BREAKDOWN_FOLDER" "$$"
843853

854+
# SLA target for search_qps (95p latency in milliseconds). Default 500ms.
855+
# Override via FEEDSIM_SLA_P95_MS env var. Prior experiments (t29, t30)
856+
# ran at 700ms to give the system more headroom past the prod-aggregator's
857+
# own end-to-end budget.
858+
sla_p95_ms="${FEEDSIM_SLA_P95_MS:-500}"
859+
sla_arg="95p:${sla_p95_ms}"
860+
844861
if [ -z "$fixed_qps" ] && [ "$auto_driver_threads" != "1" ]; then
845862
benchreps_tell_state "before search_qps"
863+
echo "search_qps SLA: ${sla_arg}"
846864
# shellcheck disable=SC2086
847-
scripts/search_qps.sh -w 15 -f 300 -s 95p:500 -P "$LEAF_PID" -B "$BREAKDOWN_FOLDER" $qps_threshold_args $no_retry_args -o "${FEEDSIM_ROOT}/${result_filename}" -- \
865+
scripts/search_qps.sh -w 15 -f 300 -s "$sla_arg" -P "$LEAF_PID" -B "$BREAKDOWN_FOLDER" $qps_threshold_args $no_retry_args -o "${FEEDSIM_ROOT}/${result_filename}" -- \
848866
build/workloads/ranking/DriverNodeRank \
849867
--server "0.0.0.0:$port" \
850868
--monitor_port "$client_monitor_port" \
@@ -856,8 +874,9 @@ main() {
856874
benchreps_tell_state "after search_qps"
857875
elif [ -z "$fixed_qps" ] && [ "$auto_driver_threads" = "1" ]; then
858876
benchreps_tell_state "before search_qps"
877+
echo "search_qps SLA: ${sla_arg}"
859878
# shellcheck disable=SC2086
860-
scripts/search_qps.sh -a -w 15 -f 300 -s 95p:500 -P "$LEAF_PID" -B "$BREAKDOWN_FOLDER" $qps_threshold_args $no_retry_args -o "${FEEDSIM_ROOT}/${result_filename}" -- \
879+
scripts/search_qps.sh -a -w 15 -f 300 -s "$sla_arg" -P "$LEAF_PID" -B "$BREAKDOWN_FOLDER" $qps_threshold_args $no_retry_args -o "${FEEDSIM_ROOT}/${result_filename}" -- \
861880
build/workloads/ranking/DriverNodeRank \
862881
--monitor_port "$client_monitor_port" \
863882
--server "0.0.0.0:$port" \

packages/feedsim/third_party/src/workloads/ranking/MockServicesClient.cc

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,31 @@
2020
#include <string>
2121
#include <utility>
2222

23+
#include <cstdlib>
24+
#include <cstring>
25+
2326
#include <folly/SocketAddress.h>
2427
#include <folly/io/async/AsyncSocket.h>
2528

2629
#include <thrift/lib/cpp2/async/RocketClientChannel.h>
30+
#include <thrift/lib/thrift/gen-cpp2/RpcMetadata_types.h>
2731

2832
#include "mock_services/gen-cpp2/MockServiceAsyncClient.h"
2933

34+
namespace {
35+
// LeafNodeRank uses gengetopt (not gflags) for CLI parsing, so we cannot add
36+
// CLI flags here. Read knobs from env vars instead. Set MOCK_COMPRESS_ZSTD=0
37+
// to disable per-channel ZSTD negotiation (default on).
38+
bool envBoolTrue(const char* name, bool default_value) {
39+
const char* v = std::getenv(name);
40+
if (v == nullptr) {
41+
return default_value;
42+
}
43+
return std::strcmp(v, "1") == 0 || std::strcmp(v, "true") == 0 ||
44+
std::strcmp(v, "TRUE") == 0;
45+
}
46+
} // namespace
47+
3048
namespace ranking {
3149

3250
// KeepaliveTimer fires a fire-and-forget getStatus() RPC every
@@ -100,12 +118,18 @@ MockServicesClient::MockServicesClient(
100118
// RocketClientChannel must be created on the EventBase thread. Use
101119
// runInEventBaseThreadAndWait so this constructor remains usable from
102120
// any thread (typically the main thread during ThreadStartup).
103-
evb_->runInEventBaseThreadAndWait([this, &host, port]() {
121+
const bool use_zstd = envBoolTrue("MOCK_COMPRESS_ZSTD", true);
122+
evb_->runInEventBaseThreadAndWait([this, &host, port, use_zstd]() {
104123
folly::SocketAddress addr(host, port, /*allowNameLookup=*/true);
105124
folly::AsyncSocket::UniquePtr socket(
106125
new folly::AsyncSocket(evb_, addr));
107126
auto channel =
108127
apache::thrift::RocketClientChannel::newChannel(std::move(socket));
128+
if (use_zstd) {
129+
apache::thrift::CompressionConfig compressionConfig;
130+
compressionConfig.codecConfig().ensure().set_zstdConfig();
131+
channel->setDesiredCompressionConfig(compressionConfig);
132+
}
109133
client_ =
110134
std::make_unique<mock_services::MockServiceAsyncClient>(
111135
std::move(channel));

packages/feedsim/third_party/src/workloads/ranking/generators/RankingGenerators.h

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,21 @@ inline ranking::RankingPayloadVecMap generateRandomVecMap(size_t length) {
9999
return map;
100100
}
101101

102+
// Per-payload-map entry count. Cut from 5 to 2 to bring the response
103+
// wire-size and serialization CPU closer to prod multifeed/aggregator_main:
104+
// before, FS-side RPC-Serialization was 21% of CPU with
105+
// `RankingObject::write` self-time = 54% of that bucket; prod's analogous
106+
// `GetStoriesResponse` averages ~12 simple fields per story plus one binary
107+
// blob, not 3 typed maps × N entries. See the t30 hot-func breakdown
108+
// comparison (2026-06-01) for the source data.
109+
constexpr size_t kPayloadEntriesPerMap = 2;
110+
// Actions per RankingObject. Was 5; reduced to 2 (same rationale).
111+
constexpr size_t kActionsPerObject = 2;
112+
// RankingObjects per RankingStory. Was 20; reduced to 10 to roughly
113+
// halve the per-story serialization work without changing the request
114+
// fanout shape.
115+
constexpr size_t kObjectsPerStory = 10;
116+
102117
inline ranking::RankingObject generateRandomRankingObject(
103118
size_t actions_length) {
104119
ranking::RankingObject obj;
@@ -109,10 +124,9 @@ inline ranking::RankingObject generateRandomRankingObject(
109124
obj.actorID() = static_cast<int64_t>(rand_int);
110125
obj.createTime() = static_cast<int64_t>(rand_int);
111126

112-
// FIXME(cltorres): Populate with realistic sizes
113-
obj.payloadIntMap() = generateRandomIntMap(5);
114-
obj.payloadStrMap() = generateRandomStringMap(5);
115-
obj.payloadVecMap() = generateRandomVecMap(5);
127+
obj.payloadIntMap() = generateRandomIntMap(kPayloadEntriesPerMap);
128+
obj.payloadStrMap() = generateRandomStringMap(kPayloadEntriesPerMap);
129+
obj.payloadVecMap() = generateRandomVecMap(kPayloadEntriesPerMap);
116130

117131
auto actions_ref = obj.actions();
118132
auto& actions = *actions_ref;
@@ -132,11 +146,10 @@ inline ranking::RankingStory generateRandomRankingStory(
132146
auto objects_ref = story.objects();
133147
auto& objects = *objects_ref;
134148
objects.reserve(ranking_objects_length);
135-
// TODO(cltorres): Determine distribution of Actions per ranking object
136149
std::generate_n(
137150
std::back_inserter(objects),
138151
ranking_objects_length,
139-
std::bind(generateRandomRankingObject, 5));
152+
std::bind(generateRandomRankingObject, kActionsPerObject));
140153
story.weight() = static_cast<double>(rand_int);
141154
story.storyType() = static_cast<ranking::RankingStoryType>(
142155
rand_int %
@@ -152,11 +165,10 @@ inline ranking::RankingResponse generateRandomRankingResponse(
152165
auto rankingStories_ref = resp.rankingStories();
153166
auto& rankingStories = *rankingStories_ref;
154167
rankingStories.reserve(ranking_stories_length);
155-
// TODO(cltorres): Determine distribution of ranking objects per story
156168
std::generate_n(
157169
std::back_inserter(rankingStories),
158170
ranking_stories_length,
159-
std::bind(generateRandomRankingStory, 20));
171+
std::bind(generateRandomRankingStory, kObjectsPerStory));
160172
auto objectCounts_ref = resp.objectCounts();
161173
auto& objectCounts = *objectCounts_ref;
162174
objectCounts.reserve(ranking_stories_length);

packages/feedsim/third_party/src/workloads/ranking/mock_services/MockServiceMain.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ DECLARE_int32(latency_cap_us);
5252
DECLARE_int32(latency_offset_us);
5353
DECLARE_int32(latency_skip_threshold_us);
5454

55+
// NOTE: TLS support intentionally not wired here. The open-source FBThrift
56+
// v2026.01.05.00 Rocket transport requires a fizz-based AsyncTransport (not
57+
// plain AsyncSSLSocket) on the client side; without it, TLS-REQUIRED servers
58+
// reject the first Rocket setup frame before SSL handshake even begins. See
59+
// the Encryption gap analysis in the t31 memo for the closure plan.
60+
5561
int main(int argc, char** argv) {
5662
folly::Init init(&argc, &argv);
5763

0 commit comments

Comments
 (0)