Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

errors: pager API errors refactor #1160

Open
wants to merge 14 commits into
base: main
Choose a base branch
from

Conversation

muzarski
Copy link
Contributor

@muzarski muzarski commented Dec 27, 2024

Ref: #519

Motivation

There are three main objectives:

Purge pager.rs module of QueryError

It's yet another module where usage of QueryError was abused. It's taken care of in this PR

Narrow return error type of [poll_]next() methods on iterators/streams

They now return a self-contained NextRow error. It's independent of QueryError.

Step forward narrowing error type of metadata related functions

Currently all top-level metadata related functions/methods (e.g. Session::refresh_metadata) return QueryError. This is because low-level methods use QueryPager API under the hood. Before this PR, the pager API would return QueryError. In the follow-up PR we will continue on purging the metadata methods of QueryError. It will be replaced with an error type designated for these operations - namely MetadataError.

Note: I did not check the All commits compile, pass static checks and pass test. box, since penultimate commit breaks tests for cassandra. The fix for this is introduced in the last commit. I believe that this is cleaner than introducing the fix in the same commit that change the flow of errors.

Pre-review checklist

  • I have split my patch into logically separate commits.
  • All commit messages clearly explain what they change and why.
  • [ ] I added relevant tests for new features and bug fixes.
  • All commits compile, pass static checks and pass test.
  • PR description sums up the changes and reasons why they should be introduced.
  • I have provided docstrings for the public items that I want to introduce.
  • [ ] I have adjusted the documentation in ./docs/source/.
  • I added appropriate Fixes: annotations to PR description.

@muzarski muzarski marked this pull request as draft December 27, 2024 07:23
@muzarski muzarski self-assigned this Dec 27, 2024
Copy link

github-actions bot commented Dec 27, 2024

cargo semver-checks detected some API incompatibilities in this PR.
Checked commit: dc72120

See the following report for details:

cargo semver-checks output
./scripts/semver-checks.sh --baseline-rev f9f0940dec71b0c6762d813af2da6b4a2578058e
+ cargo semver-checks -p scylla -p scylla-cql --baseline-rev f9f0940dec71b0c6762d813af2da6b4a2578058e
     Cloning f9f0940dec71b0c6762d813af2da6b4a2578058e
    Building scylla v0.15.0 (current)
       Built [  22.134s] (current)
     Parsing scylla v0.15.0 (current)
      Parsed [   0.055s] (current)
    Building scylla v0.15.0 (baseline)
       Built [  21.914s] (baseline)
     Parsing scylla v0.15.0 (baseline)
      Parsed [   0.049s] (baseline)
    Checking scylla v0.15.0 -> v0.15.0 (no change)
     Checked [   0.113s] 107 checks: 98 pass, 9 fail, 0 warn, 0 skip

--- failure constructible_struct_adds_field: externally-constructible struct adds field ---

Description:
A pub struct constructible with a struct literal has a new pub field. Existing struct literals must be updated to include the new field.
        ref: https://doc.rust-lang.org/reference/expressions/struct-expr.html
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.38.0/src/lints/constructible_struct_adds_field.ron

Failed in:
  field StructuredHistory.requests in /home/runner/work/scylla-rust-driver/scylla-rust-driver/scylla/src/observability/history.rs:255

--- failure enum_marked_non_exhaustive: enum marked #[non_exhaustive] ---

Description:
A public enum has been marked #[non_exhaustive]. Pattern-matching on it outside of its crate must now include a wildcard pattern like `_`, or it will fail to compile.
        ref: https://doc.rust-lang.org/cargo/reference/semver.html#attr-adding-non-exhaustive
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.38.0/src/lints/enum_marked_non_exhaustive.ron

Failed in:
  enum PartitionKeyError in /home/runner/work/scylla-rust-driver/scylla-rust-driver/scylla/src/statement/prepared_statement.rs:482
  enum PartitionKeyError in /home/runner/work/scylla-rust-driver/scylla-rust-driver/scylla/src/statement/prepared_statement.rs:482

--- failure enum_missing: pub enum removed or renamed ---

Description:
A publicly-visible enum cannot be imported by its prior path. A `pub use` may have been removed, or the enum itself may have been renamed or removed entirely.
        ref: https://doc.rust-lang.org/cargo/reference/semver.html#item-remove
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.38.0/src/lints/enum_missing.ron

Failed in:
  enum scylla::observability::history::QueryHistoryResult, previously in file /home/runner/work/scylla-rust-driver/scylla-rust-driver/target/semver-checks/git-f9f0940dec71b0c6762d813af2da6b4a2578058e/2617f21fcf0fbfe17a5c5f14918ea0b21b68469e/scylla/src/observability/history.rs:265

--- failure enum_variant_added: enum variant added on exhaustive enum ---

Description:
A publicly-visible enum without #[non_exhaustive] has a new variant.
        ref: https://doc.rust-lang.org/cargo/reference/semver.html#enum-variant-new
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.38.0/src/lints/enum_variant_added.ron

Failed in:
  variant HistoryEvent:NewRequest in /home/runner/work/scylla-rust-driver/scylla-rust-driver/scylla/src/observability/history.rs:90
  variant HistoryEvent:RequestSuccess in /home/runner/work/scylla-rust-driver/scylla-rust-driver/scylla/src/observability/history.rs:91
  variant HistoryEvent:RequestError in /home/runner/work/scylla-rust-driver/scylla-rust-driver/scylla/src/observability/history.rs:92
  variant LegacyNextRowError:NextRowError in /home/runner/work/scylla-rust-driver/scylla-rust-driver/scylla/src/client/pager.rs:1180

--- failure enum_variant_missing: pub enum variant removed or renamed ---

Description:
A publicly-visible enum has at least one variant that is no longer available under its prior name. It may have been renamed or removed entirely.
        ref: https://doc.rust-lang.org/cargo/reference/semver.html#item-remove
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.38.0/src/lints/enum_variant_missing.ron

Failed in:
  variant HistoryEvent::NewQuery, previously in file /home/runner/work/scylla-rust-driver/scylla-rust-driver/target/semver-checks/git-f9f0940dec71b0c6762d813af2da6b4a2578058e/2617f21fcf0fbfe17a5c5f14918ea0b21b68469e/scylla/src/observability/history.rs:90
  variant HistoryEvent::QuerySuccess, previously in file /home/runner/work/scylla-rust-driver/scylla-rust-driver/target/semver-checks/git-f9f0940dec71b0c6762d813af2da6b4a2578058e/2617f21fcf0fbfe17a5c5f14918ea0b21b68469e/scylla/src/observability/history.rs:91
  variant HistoryEvent::QueryError, previously in file /home/runner/work/scylla-rust-driver/scylla-rust-driver/target/semver-checks/git-f9f0940dec71b0c6762d813af2da6b4a2578058e/2617f21fcf0fbfe17a5c5f14918ea0b21b68469e/scylla/src/observability/history.rs:92
  variant LegacyNextRowError::QueryError, previously in file /home/runner/work/scylla-rust-driver/scylla-rust-driver/target/semver-checks/git-f9f0940dec71b0c6762d813af2da6b4a2578058e/2617f21fcf0fbfe17a5c5f14918ea0b21b68469e/scylla/src/client/pager.rs:1175

--- failure struct_missing: pub struct removed or renamed ---

Description:
A publicly-visible struct cannot be imported by its prior path. A `pub use` may have been removed, or the struct itself may have been renamed or removed entirely.
        ref: https://doc.rust-lang.org/cargo/reference/semver.html#item-remove
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.38.0/src/lints/struct_missing.ron

Failed in:
  struct scylla::observability::history::QueryId, previously in file /home/runner/work/scylla-rust-driver/scylla-rust-driver/target/semver-checks/git-f9f0940dec71b0c6762d813af2da6b4a2578058e/2617f21fcf0fbfe17a5c5f14918ea0b21b68469e/scylla/src/observability/history.rs:18
  struct scylla::observability::history::QueryHistory, previously in file /home/runner/work/scylla-rust-driver/scylla-rust-driver/target/semver-checks/git-f9f0940dec71b0c6762d813af2da6b4a2578058e/2617f21fcf0fbfe17a5c5f14918ea0b21b68469e/scylla/src/observability/history.rs:257

--- failure struct_pub_field_missing: pub struct's pub field removed or renamed ---

Description:
A publicly-visible struct has at least one public field that is no longer available under its prior name. It may have been renamed or removed entirely.
        ref: https://doc.rust-lang.org/cargo/reference/semver.html#item-remove
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.38.0/src/lints/struct_pub_field_missing.ron

Failed in:
  field queries of struct StructuredHistory, previously in file /home/runner/work/scylla-rust-driver/scylla-rust-driver/target/semver-checks/git-f9f0940dec71b0c6762d813af2da6b4a2578058e/2617f21fcf0fbfe17a5c5f14918ea0b21b68469e/scylla/src/observability/history.rs:253

--- failure trait_method_added: pub trait method added ---

Description:
A non-sealed public trait added a new method without a default implementation, which breaks downstream implementations of the trait
        ref: https://doc.rust-lang.org/cargo/reference/semver.html#trait-new-item-no-default
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.38.0/src/lints/trait_method_added.ron

Failed in:
  trait method scylla::observability::history::HistoryListener::log_request_start in file /home/runner/work/scylla-rust-driver/scylla-rust-driver/scylla/src/observability/history.rs:40
  trait method scylla::observability::history::HistoryListener::log_request_success in file /home/runner/work/scylla-rust-driver/scylla-rust-driver/scylla/src/observability/history.rs:43
  trait method scylla::observability::history::HistoryListener::log_request_error in file /home/runner/work/scylla-rust-driver/scylla-rust-driver/scylla/src/observability/history.rs:46

--- failure trait_method_missing: pub trait method removed or renamed ---

Description:
A trait method is no longer callable, and may have been renamed or removed entirely.
        ref: https://doc.rust-lang.org/cargo/reference/semver.html#major-any-change-to-trait-item-signatures
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.38.0/src/lints/trait_method_missing.ron

Failed in:
  method log_query_start of trait HistoryListener, previously in file /home/runner/work/scylla-rust-driver/scylla-rust-driver/target/semver-checks/git-f9f0940dec71b0c6762d813af2da6b4a2578058e/2617f21fcf0fbfe17a5c5f14918ea0b21b68469e/scylla/src/observability/history.rs:40
  method log_query_success of trait HistoryListener, previously in file /home/runner/work/scylla-rust-driver/scylla-rust-driver/target/semver-checks/git-f9f0940dec71b0c6762d813af2da6b4a2578058e/2617f21fcf0fbfe17a5c5f14918ea0b21b68469e/scylla/src/observability/history.rs:43
  method log_query_error of trait HistoryListener, previously in file /home/runner/work/scylla-rust-driver/scylla-rust-driver/target/semver-checks/git-f9f0940dec71b0c6762d813af2da6b4a2578058e/2617f21fcf0fbfe17a5c5f14918ea0b21b68469e/scylla/src/observability/history.rs:46

     Summary semver requires new major version: 9 major and 0 minor checks failed
    Finished [  45.658s] scylla
    Building scylla-cql v0.4.0 (current)
       Built [  10.787s] (current)
     Parsing scylla-cql v0.4.0 (current)
      Parsed [   0.034s] (current)
    Building scylla-cql v0.4.0 (baseline)
       Built [  10.918s] (baseline)
     Parsing scylla-cql v0.4.0 (baseline)
      Parsed [   0.034s] (baseline)
    Checking scylla-cql v0.4.0 -> v0.4.0 (no change)
     Checked [   0.111s] 107 checks: 107 pass, 0 skip
     Summary no semver update required
    Finished [  22.440s] scylla-cql
make: *** [Makefile:61: semver-rev] Error 1

@github-actions github-actions bot added the semver-checks-breaking cargo-semver-checks reports that this PR introduces breaking API changes label Dec 27, 2024
@muzarski muzarski force-pushed the iterator-errors-refactor branch 2 times, most recently from c4b17fe to 3cfdcc7 Compare December 30, 2024 13:16
Previously, it would return `Option<Result<_, _>>`. This option
was meant to represent an empty plan. This additional layer was unnecessary
and introduced additional noise.

In addition, notice that following part in speculative_execution::execute():
```
res = async_tasks.select_next_some() => {
    if let Some(r) = res {
        if !can_be_ignored(&r) {
            return r;
        } else {
            last_error = Some(r)
        }
    }
    if async_tasks.is_empty() && retries_remaining == 0 {
        return last_error.unwrap_or({
            Err(EMPTY_PLAN_ERROR)
        });
    }
}
```
would unnecessarily try to run remaining retries if `None` was returned. This means,
we would do the retries (and sleep in between retries) with empty plan.

Now, the empty plan error is returned instead of option, and can be handled
accordinly in `can_be_ignoed` (we decide not to ignore such error - no point
in retrying on another node - there is no other node).

I also added a regression test case.
The test's timeout is set to 5s. What we try to do, is to run a request
with speculative execution policy (6s retry interval) and a LBP that always
returns an empty plan. The expected behaviour is that the test completes in
less than 5s (no timeout occurs). Otherwise, this would imply that driver
was waiting 6s for speculative retry (which was the case before this commit).
I've run the test before the change, and it indeed fails.
Introduced "new" error type and adjusted session.rs, speculative_execution
module and iterator module to this type.

This error represents a definite request failure (after potential retries).
Introduced:
- RequestTimeout(std::time::Duration) - for requests that timed out with provided
  client timeout
- SchemaAgreementTimeout(std::time::Duration) - for schema agreement timeouts
RequestError will be passed to HistoryListener when the request either fails
or times out.
- `log_attempt_error` will now accept an error representing a single
   request failure - namely `RequestAttemptError`
- `log_query_error` will now accept RequestError, which represents a definite
   request failure. This is a superset of RequestAttemptError, as it also
   contains information about potential timeout, empty plan etc.
I marked `PartitionKeyError` as non_exhaustive. Narrowed the return type
of remaining funtions that returned `QueryError` to `PartitionKeyError`.
Added an explicit conversion function PartitionKeyError -> QueryError.
Narrowed the error types in multiple places in internal API of
iterator module. Now the error type we manipulate on mainly is
`NextPageError` (instead of `QueryError`).

I did not change the return type of public methods yet.
I want to do it in a separate commit.
Without this change, tests fail, because we propagate the error for
Cassandra clusters, instead of ignoring it.
@muzarski muzarski force-pushed the iterator-errors-refactor branch from 3cfdcc7 to dc72120 Compare January 16, 2025 14:44
@muzarski muzarski marked this pull request as ready for review January 16, 2025 15:40
@muzarski muzarski requested review from wprzytula and Lorak-mmk and removed request for wprzytula January 16, 2025 15:41
@muzarski muzarski mentioned this pull request Jan 16, 2025
6 tasks
@muzarski muzarski changed the title errors: iterator API errors refactor errors: pager API errors refactor Jan 16, 2025
@muzarski muzarski added this to the 0.16.0 milestone Jan 16, 2025
@muzarski muzarski added the API-stability Part of the effort to stabilize the API label Jan 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API-stability Part of the effort to stabilize the API semver-checks-breaking cargo-semver-checks reports that this PR introduces breaking API changes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants