Skip to content

Commit b0051fe

Browse files
committed
test_default_policy_is_tablet_aware: Better tablet info filling
This commit switches from using double loop with 100 executions in each iter, to sending statement everywhere for each tablet. Why? - It is easier to understand, so no more wall of text - It is faster (~1.2 seconds faster). - It is more resilient, because we have 100% confidence that each statement reached non-replica. One thing we lose is that test no longer checks receiving feedbacks when using DefaultPolicy, but this is not really useful. The important part is checking that we receive no feedbacks when we have info. The only way for the removed part to fail (apart from migrations and other stuff Scylla inflicts on us) is if driver can magically predict tablet info. I'd be happy if it gets magical powers, so I'm not worried about the removed part.
1 parent 209fcd3 commit b0051fe

File tree

1 file changed

+18
-38
lines changed

1 file changed

+18
-38
lines changed

scylla/tests/integration/load_balancing/tablets.rs

Lines changed: 18 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -205,42 +205,21 @@ async fn populate_internal_driver_tablet_info(
205205
value_per_tablet: &[(i32, i32)],
206206
feedback_rxs: &mut [UnboundedReceiver<(ResponseFrame, Option<u16>)>],
207207
) -> Result<(), String> {
208-
// When the driver never received tablet info for any tablet in a given table,
209-
// then it will not be aware that the table is tablet-based and fall back
210-
// to token-ring routing for this table.
211-
// After it receives any tablet for this table:
212-
// - tablet-aware routing will be used for tablets that the driver has locally
213-
// - non-token-aware routing will be used for other tablets (which basically means
214-
// sending the requests to random nodes)
215-
// In the following code I want to make sure that the driver fetches info
216-
// about all the tablets in the table.
217-
// Obvious way to do this would be to, for each tablet, send some requests (here some == 100)
218-
// and expect that at least one will land on non-replica and return tablet feedback.
219-
// This mostly works, but there is a problem: initially driver has no
220-
// tablet information at all for this table so it will fall back to token-ring routing.
221-
// It is possible that token-ring replicas and tablet replicas are the same
222-
// for some tokens. If it happens for the first token that we use in this loop,
223-
// then no matter how many requests we send we are not going to receive any tablet feedback.
224-
// The solution is to iterate over tablets twice.
225-
//
226-
// First iteration guarantees that the driver will receive at least one tablet
227-
// for this table (it is statistically improbable for all tokens used here to have the same
228-
// set of replicas for tablets and token-ring). In practice it will receive all or almost all of the tablets.
229-
//
230-
// Second iteration will not use token-ring routing (because the driver has some tablets
231-
// for this table, so it is aware that the table is tablet based),
232-
// which means that for unknown tablets it will send requests to random nodes,
233-
// and definitely fetch the rest of the tablets.
234208
let mut total_tablets_with_feedback = 0;
235-
for values in value_per_tablet.iter().chain(value_per_tablet.iter()) {
209+
for values in value_per_tablet.iter() {
236210
info!(
237211
"First loop, trying key {:?}, token: {}",
238212
values,
239213
prepared.calculate_token(&values).unwrap().unwrap().value()
240214
);
241-
try_join_all((0..100).map(|_| async { session.execute_unpaged(&prepared, values).await }))
242-
.await
243-
.unwrap();
215+
execute_prepared_statement_everywhere(
216+
session,
217+
&session.get_cluster_state(),
218+
prepared,
219+
values,
220+
)
221+
.await
222+
.unwrap();
244223
let feedbacks: usize = feedback_rxs.iter_mut().map(count_tablet_feedbacks).sum();
245224
if feedbacks > 0 {
246225
total_tablets_with_feedback += 1;
@@ -297,15 +276,16 @@ async fn run_test_default_policy_is_tablet_aware_attempt(
297276
.await
298277
}
299278

300-
/// Tests that, when using DefaultPolicy with TokenAwareness and querying table
301-
/// that uses tablets:
302-
/// 1. When querying data that belongs to tablet we didn't receive yet we will
303-
/// receive this tablet at some point.
304-
/// 2. When we have all tablets info locally then we'll never receive tablet info.
279+
/// Tests that, when:
280+
/// - Using DefaultPolicy with TokenAwareness
281+
/// - Querying table that uses tablets
282+
/// - Driver has all driver info fetched locally
283+
/// Then we'll never receive tablet info.
305284
///
306-
/// The test first sends 100 queries per tablet and expects to receive tablet info.
307-
/// After that we know we have all the info. The test sends the statements again
308-
/// and expects to not receive any tablet info.
285+
/// The test first sends, to each possible target, one insert request per tablet.
286+
/// It expects to get tablet feedback for each tablet.
287+
/// After that we know we have all the info. The test sends the same insert request
288+
/// per tablet, this time using DefaultPolicy, and expects to not get any feedbacks.
309289
#[cfg_attr(scylla_cloud_tests, ignore)]
310290
#[tokio::test]
311291
#[ntest::timeout(30000)]

0 commit comments

Comments
 (0)