Commit Graph

848 Commits

Author SHA1 Message Date
Pavel Emelyanov
11c99fc41b table: Don't use global gossiper
The table::get_hit_rate needs gossiper to get hitrates state from.
There's no way to carry gossiper reference on the table itself, so it's
up to the callers of that method to provide it. Fortunately, there's
only one caller -- the proxy -- but the call chain to carry the
reference it not very short ... oh, well.

Signed-off-by: Pavel Emelyanov <xemul@scylladb.com>
2022-05-03 10:33:08 +03:00
Benny Halevy
e88871f4ec replica: database: move shard_of implementation to mutation layer
We don't need the database to determine the shard of the mutation,
only its schema. So move the implementation to the respecive
definitions of mutation and frozen_mutation.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>

Closes #10430
2022-04-27 14:40:24 +03:00
Avi Kivity
582802825a treewide: use system-#include (angle brackets) for seastar
Seastar is an external library from Scylla's point of view so
we should use the angle bracket #include style. Most of the source
follows this, this patch fixes a few stragglers.

Also fix cases of #include which reached out to seastar's directory
tree directly, via #include "seastar/include/sesatar/..." to
just refer to <seastar/...>.

Closes #10433
2022-04-26 14:46:42 +03:00
Avi Kivity
469bca5369 storage_proxy: coroutinize mutate_locally (vector overload)
The do_with() means we have an unconditional allocation, so we can
justify the coroutine's allocation (replacing it). Meanwhile,
coroutine::parallel_for_each() reduces an allocation if mutate_locally()
blocks.

Closes #10387
2022-04-19 10:59:16 +03:00
Avi Kivity
36aee57978 storage_proxy: convert rpc handlers from lambdas to member functions
Currently, rpc handlers are all lambdas inside
storage_proxy::init_messaging_service(). This means any stack trace
refers to storage_proxy::init_messaging_service::lambda#n instead of
a meaningful function name, and it makes init_messaging_service()
very intimidating.

Fix that by moving all such lambdas to regular member functions.
This is easy now that they don't capture anything except `this`,
which we provide during registration via std::bind_front().

A few #includes and forward declarations had to be added to
storage_proxy.hh. This is unfortunate, but can only be solved
by splitting storage_proxy into a client part and a server part.
2022-04-17 19:03:06 +03:00
Avi Kivity
f7e8109b16 storage_proxy: don't capture messaging_service in server callbacks
We'd like to make the server callbacks member functions, rather
than lambdas, so we need to eliminate their captures. This patch
eliminats 'ms' by referringn to the already existing member '_messaging'
instead.
2022-04-17 17:55:05 +03:00
Avi Kivity
4cac2eb43e storage_proxy: don't capture migration_manager in server callbacks
We'd like to make the server callbacks member functions, rather
than lambdas, so we need to eliminate their captures. This patch
eliminates 'mm' by making it a member variable and capturing 'this'
instead. In one case 'mm' was used by a handle_write() intermediate
lambda so we have to make that non-static and capture it too.

uninit_messaging_service() clears the member variable to preserve
the same lifetime 'mm' had before, in case that's important.
2022-04-17 17:54:51 +03:00
Gleb Natapov
a3e8ae0979 storage_proxy: fix silencing of remote read errors
Filtering remote rpc errors based on exception type did not work because
the remote errors were reported as std::runtime_error and all rpc
exceptions inherit from it. New rpc propagates remote errors using
special type rpc::remote_verb_error now, so we can filter on that
instead.

Fixes #10339

Message-Id: <YlQYV5G6GksDytGp@scylladb.com>
2022-04-11 18:53:25 +03:00
Pavel Emelyanov
9fdb49c86a Merge 'fix hang on shutdown while ddl query is running and there is no quorum' from Gleb
A node that runs DDL query while its cluster does not have a quorum
cannot be shutdown since the query is not abortable. The series makes it
abortable and also fixes the order in which components are shutdown to
avoid the deadlock.

* gleb/raft_shutdown_v4 of git@github.com:scylladb/scylla-dev.git:
  migration_manager: drain migration manager before stopping protocol servers on shutdown
  migration_manager: pass abort source to raft primitives
  storage_proxy: relax some read error reporting
2022-04-04 17:25:13 +03:00
Gleb Natapov
1409b885a0 storage_proxy: relax some read error reporting
Silence request_aborted read error since it is expected to happen suring
shutdown and report remote rpc errors as warnings instead of errors since
if they are indeed server they should be handled by the rpc client, but
OTOH some non critical errors do expect to happen during shutdown.
2022-03-31 10:00:29 +03:00
Pavel Emelyanov
965d2a0a4f code,system_keyspace: Remove system_keyspace::get_local_host_id()
The host id is cached on db::config object that's available in
all the places that need it. This allows removing the method in
question from the system_keyspace and not caring that anyone that
needs host_id would have to depend on system_keyspace instance.

Signed-off-by: Pavel Emelyanov <xemul@scylladb.com>
2022-03-25 13:21:59 +03:00
Piotr Dulikowski
2415a1d169 abstract_read_resolver: bring back cancelling timeout timer on read failure
Recent PR #10092 (propagating read timeouts on coordinator without
throwing) accidentally removed a line which cancelled
`abstract_read_resolver`'s `_timeout` timer after a read failure.
Because of that, it might happen that after a read failure the timer is
triggered and the `_done_promise` is set twice which triggers an assert
in seastar.

This commit brings back the line which cancels the timeout timer.

Fixes: #10193

Closes #10206
2022-03-14 09:43:32 +01:00
Piotr Dulikowski
e5922e650e storage_proxy: resultify (do_)query
Adjusts do_query so that it propagates and returns failed results. The
query_result method is added which is result-aware, and the old query
method was changed to call query_result.
2022-02-22 16:08:52 +01:00
Piotr Dulikowski
e39c5b6eba storage_proxy: resultify query_singular
Now, query_singular propagates and returns failed results without
rethrowing them.
2022-02-22 16:08:52 +01:00
Piotr Dulikowski
2f5f746ae2 storage_proxy: propagate failed results through query_partition_key_range
Now, query_partition_key_range propagates the failed result from
query_partition_key_range_concurrent.
2022-02-22 16:08:52 +01:00
Piotr Dulikowski
608032b2b5 storage_proxy: resultify query_partition_key_range_concurrent
Now, query_partition_key_range_concurrent propagates and returns
exceptions as values, if possible.
2022-02-22 16:08:52 +01:00
Piotr Dulikowski
10923d9d58 storage_proxy: modify handle_read_error to also handle exception containers
Now, storage_proxy::handle_read_error can work with both exception
containers and exception_ptrs.
2022-02-22 16:08:52 +01:00
Piotr Dulikowski
89fe804a1a abstract_read_executor: return result from execute() 2022-02-22 16:08:52 +01:00
Piotr Dulikowski
15fa5e30f5 abstract_read_executor: return and handle result from has_cl()
The has_cl() method is changed to return a future with a result. The
result returned from has_cl() is handled without throwing.
2022-02-22 16:08:52 +01:00
Piotr Dulikowski
68b5b84fbe storage_proxy: resultify handling errors from read-repair
Now, failed results returned from read-repair are handled without
throwing.
2022-02-22 16:08:52 +01:00
Piotr Dulikowski
dd860c70ce abstract_read_executor::reconcile: resultise handling of data_resolver->done()
Now, the logic of handling exceptions returned in reconcile() from
data_resolver->done() was changed so that the failed result does not
need to be converted to an exceptional future.
2022-02-22 16:08:52 +01:00
Piotr Dulikowski
5accfd8dae abstract_read_executor::execute: resultify handling of data_resolver->done()
Now, the logic of handling exceptions returned in execute() from
data_resolver->done() was changed so that the failed result does not
need to be converted to an exceptional future.
2022-02-22 16:08:52 +01:00
Piotr Dulikowski
ee2c4725c3 abstract_read_executor: resultify _result_promise
Adjusts the type of _result_promise so that it holds a result.
2022-02-22 16:08:52 +01:00
Piotr Dulikowski
e7f960d041 abstract_read_executor: return result from done() 2022-02-22 16:08:52 +01:00
Piotr Dulikowski
28d562ddf6 abstract_read_resolver: fail promises by passing exception as value
Now, on read timeouts and failures, _cl_promise and _done_promise is set
to a failed result instead of an exceptional promise.
2022-02-22 16:08:52 +01:00
Piotr Dulikowski
5438973c9d abstract_read_resolver: resultify promises
Changes the types of _done_promise and _cl_promise so that they hold a
result.
2022-02-22 16:08:52 +01:00
Piotr Dulikowski
adfd9d2f7a abstract_read_resolver::fail_request: make non-virtual
This method is not overrided by any of the derived classes, so it does
not need to be virtual.

(cherry picked from commit b7fb93dc46531bca8db535301a069df52991f9d9)
2022-02-17 12:34:37 +02:00
Avi Kivity
7cc43f8aa8 Merge 'utils: add result_try and result_futurize_try' from Piotr Dulikowski
Adds `utils::result_try` and `utils::result_futurize_try` - functions which allow to convert existing try..catch blocks into a version which handles C++ exceptions, failed results with exception containers and, depending on the function variant, exceptional futures using the same exception handling logic.

For example, you can convert the following try..catch block:

    try {
        return a_function_that_may_throw();
    } catch (const my_exception& ex) {
        return 123;
    } catch (...) {
        throw;
    }

...to this:

    return utils::result_try([&] {
        return a_function_that_may_throw_or_return_a_failed_result();
    },  utils::result_catch<my_exception>([&] (const Ex&) {
        return 123;
    }), utils::result_catch_dots([&] (auto&& handle) {
        return handle.into_result();
    });

Similarly, `utils::result_futurize_try` can be used to migrate `then_wrapped` or `f.handle_exception()` constructs.

As an example of the usability of the new constructs, two places in the current code which need to simultaneously handle exceptions and failed results are converted to use `result_try` and `result_futurize_try`.

Results of `perf_simple_query --smp 1 --operations-per-shard 1000000 --write`:

```
127041.61 tps ( 67.2 allocs/op,  14.2 tasks/op,   52422 insns/op)
126958.60 tps ( 67.2 allocs/op,  14.2 tasks/op,   52409 insns/op)
127088.37 tps ( 67.2 allocs/op,  14.2 tasks/op,   52411 insns/op)
127560.84 tps ( 67.2 allocs/op,  14.2 tasks/op,   52424 insns/op)
127826.61 tps ( 67.2 allocs/op,  14.2 tasks/op,   52406 insns/op)

126801.02 tps ( 67.2 allocs/op,  14.2 tasks/op,   52420 insns/op)
125371.51 tps ( 67.2 allocs/op,  14.2 tasks/op,   52425 insns/op)
126498.51 tps ( 67.2 allocs/op,  14.2 tasks/op,   52427 insns/op)
126359.41 tps ( 67.2 allocs/op,  14.2 tasks/op,   52423 insns/op)
126298.27 tps ( 67.2 allocs/op,  14.2 tasks/op,   52410 insns/op)
```

The number of tasks and allocations is unchanged. The number of instructions per operations seems similar, it may have increased slightly (by 10-20) but it's hard to tell for sure because of the noisiness of the results.

Tests: unit(dev)

Closes #10045

* github.com:scylladb/scylla:
  transport: use result_try in process_request_one
  storage_proxy: use result_futurize_try in mutate_end
  storage_proxy: temporarily throw exception from result in mutate_end
  utils: add result_try and result_futurize_try
2022-02-13 19:38:13 +02:00
Piotr Dulikowski
6abeec6299 utils/result: split into combinators and loop file
Segregates result utilities into:

- result.hh - basic definitions related to results with exception
  containers,
- result_combinators.hh - combinators for working with results in
  conjunction with futures,
- result_loop.hh - loop-like combinators, currently has only
  result_parallel_for_each.

The motivation for the split is:

1. In headers, usually only result.hh will be needed, so no need to
   force most .cc files to compile definitions from other files,
2. Less files need to be recompiled when a combinator is added to
   result_combinators or result_loop.

As a bonus, `result_with_exception` was moved from `utils::internal` to
just `utils`.
2022-02-10 18:19:05 +01:00
Piotr Dulikowski
98bde8d6d2 storage_proxy: use result_futurize_try in mutate_end
Adapts the mutate_end exception handling logic so that it uses the new
utils::result_futurize_try function to handle both exceptional futures
and failed results in an unified way.
2022-02-10 17:35:32 +01:00
Piotr Dulikowski
d5d24a5140 storage_proxy: temporarily throw exception from result in mutate_end
Temporarily removes the logic which handles failed results in a
non-throwing way. Exceptions from failed results are thrown and handled
in try..catch.

The reason for this change is that it makes the following commit, which
migrates the whole try..catch block to utils::result_futurize_try much
nicer. The next commit will also bring back the non-throwing handling of
the failed result.
2022-02-10 17:35:32 +01:00
Piotr Dulikowski
4c1eae7600 storage_proxy: change mutate_with_triggers to return future<result<>>
Changes the interface of `mutate_with_triggers` so that it returns
`future<result<>>` instead of `future<>`. No intermediate
`mutate_with_triggers_result` method is introduced because all call
sites will be changed in this PR so that they properly handle failed
`result<>`s with exceptions-as-values.
2022-02-08 11:08:42 +01:00
Piotr Dulikowski
7ed668a177 storage_proxy: add mutate_atomically_result
Similarly to `mutate_result` introduced in the previous commit,
`mutate_atomically_result` is introduced which returns some exceptions
inside `result<>`. The pre-existing `mutate_atomically` keeps the same
interface but uses `mutate_atomically_result` internally, converting
failed `result<>` to exceptional future if needed.
2022-02-08 11:08:42 +01:00
Piotr Dulikowski
f9ff5e7692 storage_proxy: return result<> from mutate_result
In order to be able to propagate exceptions-as-values from storage_proxy
but without having to modify all call sites of `mutate`, an in-between
method `mutate_result` is introduced which returns some exceptions
inside `result<>`. Now, `mutate` just calls the latter and converts
those exceptions to exceptional future if needed.
2022-02-08 11:08:42 +01:00
Piotr Dulikowski
f02b8614af storage_proxy: return result<> from mutate_internal
Changes the interface of `mutate_internal` so that it returns a
`future<result<>>` instead of `future<>`.
2022-02-08 11:08:42 +01:00
Piotr Dulikowski
f8bbf67e64 storage_proxy: properly propagate future from mutate_begin to mutate_end
Modifies all call sites of `mutate_begin` and `mutate_end` so that the
failed result<> created in the former is properly propagated to the
latter.
2022-02-08 11:08:42 +01:00
Piotr Dulikowski
e2893368a7 storage_proxy: handle exceptions as values in mutate_end
Instead of stupidly rethrowing the exception in failed result<>, the
`storage_proxy::mutate_end` function now inspects it with a visitor,
which does not involve any rethrows. Moreover, mutate_end now also
returns a `future<result<>>` instead of just `future<>`.
2022-02-08 11:08:42 +01:00
Piotr Dulikowski
5c00b27662 storage_proxy: let mutate_end take a future<result<>>
Changes the `storage_proxy::mutate_end` method to accept a
`future<result<>>` instead of `future<>`.

For the time being, all call call sites of that method pass a future
which is either exceptional or contains a result<> with a value.
Moreover, in case of a failed result<>, mutate_end just rethrows the
exception. Both of these will change in the upcoming commits of this PR.
2022-02-08 11:08:42 +01:00
Piotr Dulikowski
59efe085af storage_proxy: resultify mutate_begin
Changes the `storage_proxy::mutate_begin` method to return a
future<result<>>.
2022-02-08 11:08:42 +01:00
Piotr Dulikowski
3a92513ef6 storage_proxy: use result in the _ready future of write handlers
Changes the type of the _ready promise in
abstract_write_response_handler - a promise used by the coordinator
logic to wait until the write operation is complete - to keep a
`result<>` instead of `void`. Now, a timeout is signalled by setting the
promise to a value containing a `result<>` with a mutation write timeout
exception - previously it was signalled by setting the promise to an
exceptional value.

This is just a first step on a long road of throwless propagation of the
error to the cql_server - for now, a failed result is immediately
converted to an exceptional future in `storage_proxy::response_wait`.
2022-02-08 11:08:42 +01:00
Piotr Dulikowski
6ac98f26e0 storage_proxy: introduce helpers for dealing with results
Adds a number of typedefs in order to make working with coordinator
exceptions-as-values easier.
2022-02-08 11:08:42 +01:00
Michał Sala
0fe59082ec storage_proxy: extract query_ranges_to_vnodes_generator to a separate file
Such separation allows using query_ranges_to_vnodes_generator by other
services without needing a storage_proxy dependency.
2022-02-01 21:14:41 +01:00
Benny Halevy
4272dd0b28 storage_proxy: mutate_counter_on_leader_and_replicate: use container to get to shard proxy
Rather than using the global helper, get_local_storage_proxy.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
Message-Id: <20220131151516.3461049-2-bhalevy@scylladb.com>
2022-01-31 18:14:31 +02:00
Benny Halevy
8acdc6ebdc storage_proxy: paxos: don't use global storage_proxy
Rather than calling get_local_storage_proxy(),
use paxos_response_handler::_proxy.

Signed-off-by: Benny Halevy <bhalevy@scylladb.com>
Message-Id: <20220131151516.3461049-1-bhalevy@scylladb.com>
2022-01-31 18:14:31 +02:00
Nadav Har'El
1ce73c2ab3 Merge 'utils::is_timeout_exception: Ensure we handle nested exception types' from Calle Wilund
Fixes #9922

storage proxy uses is_timeout_exception to traverse different code paths.
a6202ae079 broke this (because bit rot and
intermixing), by wrapping exception for information purposes.

This adds check of nested types in exception handling, as well as a test
for the routine itself.

Closes #9932

* github.com:scylladb/scylla:
  database/storage_proxy: Use "is_timeout_exception" instead of catch match
  utils::is_timeout_exception: Ensure we handle nested exception types
2022-01-18 23:49:41 +02:00
Calle Wilund
868b572ec8 database/storage_proxy: Use "is_timeout_exception" instead of catch match
Might miss cases otherwise.

v2: Fix broken control flow
v3: Avoid throw - use make_exception_future instead.
2022-01-18 15:40:41 +00:00
Avi Kivity
fcb8d040e8 treewide: use Software Package Data Exchange (SPDX) license identifiers
Instead of lengthy blurbs, switch to single-line, machine-readable
standardized (https://spdx.dev) license identifiers. The Linux kernel
switched long ago, so there is strong precedent.

Three cases are handled: AGPL-only, Apache-only, and dual licensed.
For the latter case, I chose (AGPL-3.0-or-later and Apache-2.0),
reasoning that our changes are extensive enough to apply our license.

The changes we applied mechanically with a script, except to
licenses/README.md.

Closes #9937
2022-01-18 12:15:18 +01:00
Gleb Natapov
1db151bd75 storage_proxy: move all verbs to the IDL
Define all verbs in the IDL instead of manually codding them.
2022-01-10 14:58:28 +02:00
Gleb Natapov
ff6a0fffaf storage_proxy: convert more address vectors to inet_address_vector_replica_set 2022-01-10 13:48:20 +02:00
Avi Kivity
bbad8f4677 replica: move ::database, ::keyspace, and ::table to replica namespace
Move replica-oriented classes to the replica namespace. The main
classes moved are ::database, ::keyspace, and ::table, but a few
ancillary classes are also moved. There are certainly classes that
should be moved but aren't (like distributed_loader) but we have
to start somewhere.

References are adjusted treewide. In many cases, it is obvious that
a call site should not access the replica (but the data_dictionary
instead), but that is left for separate work.

scylla-gdb.py is adjusted to look for both the new and old names.
2022-01-07 12:04:38 +02:00