Skip to content

Commit b6a3e01

Browse files
authored
Merge pull request #1181 from muzarski/sharding-error
errors: adjust ShardingError
2 parents bb824b6 + 44cae1f commit b6a3e01

File tree

3 files changed

+71
-26
lines changed

3 files changed

+71
-26
lines changed

scylla/src/network/connection.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use crate::response::{
2929
NonErrorAuthResponse, NonErrorStartupResponse, PagingState, PagingStateResponse, QueryResponse,
3030
};
3131
use crate::routing::locator::tablets::{RawTablet, TabletParsingError};
32-
use crate::routing::{Shard, ShardInfo, Sharder};
32+
use crate::routing::{Shard, ShardInfo, Sharder, ShardingError};
3333
use crate::statement::prepared_statement::PreparedStatement;
3434
use crate::statement::{Consistency, PageSize};
3535
use bytes::Bytes;
@@ -1848,7 +1848,23 @@ pub(super) async fn open_connection(
18481848
};
18491849

18501850
// If this is ScyllaDB that we connected to, we received sharding information.
1851-
let shard_info = ShardInfo::try_from(&supported.options).ok();
1851+
let shard_info = match ShardInfo::try_from(&supported.options) {
1852+
Ok(info) => Some(info),
1853+
Err(ShardingError::NoShardInfo) => {
1854+
tracing::info!(
1855+
"[{}] No sharding information received. Proceeding with no sharding info.",
1856+
addr
1857+
);
1858+
None
1859+
}
1860+
Err(e) => {
1861+
tracing::error!(
1862+
"[{}] Error while parsing sharding information: {}. Proceeding with no sharding info.",
1863+
addr, e
1864+
);
1865+
None
1866+
}
1867+
};
18521868
let supported_compression = supported
18531869
.options
18541870
.remove(options::COMPRESSION)

scylla/src/routing/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ pub mod locator;
1313
pub mod partitioner;
1414
mod sharding;
1515

16-
pub(crate) use sharding::ShardInfo;
17-
pub use sharding::{Shard, ShardCount, Sharder, ShardingError};
16+
pub use sharding::{Shard, ShardCount, Sharder};
17+
pub(crate) use sharding::{ShardInfo, ShardingError};
1818

1919
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)]
2020

scylla/src/routing/sharding.rs

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -96,36 +96,65 @@ impl Sharder {
9696
}
9797

9898
#[derive(Clone, Error, Debug)]
99-
pub enum ShardingError {
100-
#[error("ShardInfo parameters missing")]
101-
MissingShardInfoParameter,
102-
#[error("ShardInfo parameters missing after unwrapping")]
103-
MissingUnwrapedShardInfoParameter,
104-
#[error("ShardInfo contains an invalid number of shards (0)")]
99+
pub(crate) enum ShardingError {
100+
/// This indicates that we are most likely connected to a Cassandra cluster.
101+
/// Unless, there is some serious bug in Scylla.
102+
#[error("Server did not provide any sharding information")]
103+
NoShardInfo,
104+
105+
/// A bug in scylla. Some of the parameters are present, while others are missing.
106+
#[error("Missing some sharding info parameters")]
107+
MissingSomeShardInfoParameters,
108+
109+
/// A bug in Scylla. All parameters are present, but some do not contain any values.
110+
#[error("Missing some sharding info parameter values")]
111+
MissingShardInfoParameterValues,
112+
113+
/// A bug in Scylla. Number of shards is equal to zero.
114+
#[error("Sharding info contains an invalid number of shards (0)")]
105115
ZeroShards,
106-
#[error("ParseIntError encountered while getting ShardInfo")]
116+
117+
/// A bug in Scylla. Failed to parse string to number.
118+
#[error("Failed to parse a sharding info parameter's value: {0}")]
107119
ParseIntError(#[from] std::num::ParseIntError),
108120
}
109121

122+
const SHARD_ENTRY: &str = "SCYLLA_SHARD";
123+
const NR_SHARDS_ENTRY: &str = "SCYLLA_NR_SHARDS";
124+
const MSB_IGNORE_ENTRY: &str = "SCYLLA_SHARDING_IGNORE_MSB";
125+
110126
impl<'a> TryFrom<&'a HashMap<String, Vec<String>>> for ShardInfo {
111127
type Error = ShardingError;
112128
fn try_from(options: &'a HashMap<String, Vec<String>>) -> Result<Self, Self::Error> {
113-
let shard_entry = options.get("SCYLLA_SHARD");
114-
let nr_shards_entry = options.get("SCYLLA_NR_SHARDS");
115-
let msb_ignore_entry = options.get("SCYLLA_SHARDING_IGNORE_MSB");
116-
if shard_entry.is_none() || nr_shards_entry.is_none() || msb_ignore_entry.is_none() {
117-
return Err(ShardingError::MissingShardInfoParameter);
118-
}
119-
if shard_entry.unwrap().is_empty()
120-
|| nr_shards_entry.unwrap().is_empty()
121-
|| msb_ignore_entry.unwrap().is_empty()
122-
{
123-
return Err(ShardingError::MissingUnwrapedShardInfoParameter);
124-
}
125-
let shard = shard_entry.unwrap().first().unwrap().parse::<u16>()?;
126-
let nr_shards = nr_shards_entry.unwrap().first().unwrap().parse::<u16>()?;
129+
let shard_entry = options.get(SHARD_ENTRY);
130+
let nr_shards_entry = options.get(NR_SHARDS_ENTRY);
131+
let msb_ignore_entry = options.get(MSB_IGNORE_ENTRY);
132+
133+
// Unwrap entries.
134+
let (shard_entry, nr_shards_entry, msb_ignore_entry) =
135+
match (shard_entry, nr_shards_entry, msb_ignore_entry) {
136+
(Some(shard_entry), Some(nr_shards_entry), Some(msb_ignore_entry)) => {
137+
(shard_entry, nr_shards_entry, msb_ignore_entry)
138+
}
139+
// All parameters are missing - most likely a Cassandra cluster.
140+
(None, None, None) => return Err(ShardingError::NoShardInfo),
141+
// At least one of the parameters is present, but some are missing. A bug in Scylla.
142+
_ => return Err(ShardingError::MissingSomeShardInfoParameters),
143+
};
144+
145+
// Further unwrap entries (they should be the first entries of their corresponding Vecs).
146+
let (Some(shard_entry), Some(nr_shards_entry), Some(msb_ignore_entry)) = (
147+
shard_entry.first(),
148+
nr_shards_entry.first(),
149+
msb_ignore_entry.first(),
150+
) else {
151+
return Err(ShardingError::MissingShardInfoParameterValues);
152+
};
153+
154+
let shard = shard_entry.parse::<u16>()?;
155+
let nr_shards = nr_shards_entry.parse::<u16>()?;
127156
let nr_shards = ShardCount::new(nr_shards).ok_or(ShardingError::ZeroShards)?;
128-
let msb_ignore = msb_ignore_entry.unwrap().first().unwrap().parse::<u8>()?;
157+
let msb_ignore = msb_ignore_entry.parse::<u8>()?;
129158
Ok(ShardInfo::new(shard, nr_shards, msb_ignore))
130159
}
131160
}

0 commit comments

Comments
 (0)